Variable declaration/definition

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Variable declaration/definition

Sebastian Redl
Hi,

I'm trying to clean up variable definition code. I've given VarDecl a
new method, isThisDeclarationADefinition(), and have implemented it thus:

VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition() const {
  // C++ [basic.def]p2:
  //   A declaration is a definition unless [...] it contains the 'extern'
  //   specifier or a linkage-specification and neither an initializer
[...],
  //   it declares a static data member in a class declaration [...].
  // C++ [temp.expl.spec]p15:
  //   An explicit specialization of a static data member of a template is a
  //   definition if the declaration includes an initializer; otherwise,
it is
  //   a declaration.
  // FIXME: Exact C rules?
  if (isStaticDataMember()) {
    if (isOutOfLine() && (hasInit() ||
          getTemplateSpecializationKind() != TSK_ExplicitSpecialization))
      return Definition;
    else
      return DeclarationOnly;
  }
  if (hasInit())
    return Definition;
  // AST for 'extern "C" int foo;' is annotated with 'extern'.
  if (hasExternalStorage())
    return DeclarationOnly;

  // Now, in C++, everything left is a definition, but in C, if this
variable
  // is global, it is a tentative definition.
  // FIXME: It's not a tentative definition if there's a known definite
  // definition.
  if (!getASTContext().getLang().CPlusPlus && isFileVarDecl())
    return TentativeDefinition;

  return Definition;
}

Are these semantics correct for C? Can I have a standard quote? Are
global variables marked with __thread ever tentative definitions?
The current isTentativeDefinition() will return false if there is a
definite definition elsewhere in the file; I will fix this in my
implementation. Any other problems?

Sebastian
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Variable declaration/definition

Douglas Gregor

On Jan 27, 2010, at 6:48 AM, Sebastian Redl wrote:

Hi,

I'm trying to clean up variable definition code. I've given VarDecl a
new method, isThisDeclarationADefinition(), and have implemented it thus:

VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition() const {
 // C++ [basic.def]p2:
 //   A declaration is a definition unless [...] it contains the 'extern'
 //   specifier or a linkage-specification and neither an initializer
[...],
 //   it declares a static data member in a class declaration [...].
 // C++ [temp.expl.spec]p15:
 //   An explicit specialization of a static data member of a template is a
 //   definition if the declaration includes an initializer; otherwise,
it is
 //   a declaration.
 // FIXME: Exact C rules?
 if (isStaticDataMember()) {
   if (isOutOfLine() && (hasInit() ||
         getTemplateSpecializationKind() != TSK_ExplicitSpecialization))
     return Definition;
   else
     return DeclarationOnly;
 }
 if (hasInit())
   return Definition;
 // AST for 'extern "C" int foo;' is annotated with 'extern'.
 if (hasExternalStorage())
   return DeclarationOnly;

 // Now, in C++, everything left is a definition, but in C, if this
variable
 // is global, it is a tentative definition.
 // FIXME: It's not a tentative definition if there's a known definite
 // definition.
 if (!getASTContext().getLang().CPlusPlus && isFileVarDecl())
   return TentativeDefinition;

 return Definition;
}

Are these semantics correct for C?

They look correct to me, although (as you say below) you should double-check the tentative-definition semantics against isTentativeDefinition.

Can I have a standard quote?

C99 6.9.2 sayeth:

1 If the declaration of an identifier for an object has file scope and an initializer, the declaration is an external definition for the identifier.
2 A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static, constitutes a tentative definition.

Are
global variables marked with __thread ever tentative definitions?

I think they can be... they would just get a definition of 0 in each thread.

The current isTentativeDefinition() will return false if there is a
definite definition elsewhere in the file; I will fix this in my
implementation. Any other problems?

I don't see any other issues. Thanks for working on this!

- Doug

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev