Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the confliction between declaration and definition cause undefined behavior?

For example, in one source file:

extern int a[10];
int main()
{
   (void)sizeof(a);
   return 0;
}

and in a second source file we have:

int a[20];//different with the first source 

Does the code above cause undefined behavior? As far as I know, in C it says:

All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined.

Are int[10] and int[20] compatible(in c's view)? And what about C++ standard?

Besides, if there is no second source file, is it legal to use sizeof(a) (a has just a declaration) ?

like image 701
scottxiao Avatar asked Nov 27 '18 04:11

scottxiao


2 Answers

Yes this is undefined behavior in C, they are not compatible, see C11 6.7.6.2 Array declarators paragraph 6

For two array types to be compatible, both shall have compatible element types, and if both size specifiers are present, and are integer constant expressions, then both size specifiers shall have the same constant value. If the two array types are used in a context which requires them to be compatible, it is undefined behavior if the two size specifiers evaluate to unequal values.

and ill-formed no diagnostic required in C++ from [basic.link]p11:

After all adjustments of types (during which typedefs are replaced by their definitions), the types specified by all declarations referring to a given variable or function shall be identical, except that declarations for an array object can specify array types that differ by the presence or absence of a major array bound ([dcl.array]). A violation of this rule on type identity does not require a diagnostic.

like image 167
Shafik Yaghmour Avatar answered Nov 11 '22 16:11

Shafik Yaghmour


Some implementations will treat imported and exported symbols according to the rules defined by a set of conventions for the platform which are typically described in a document which is, in modern parlance, called the Application Binary Interface. If one module (compilation unit) exports an symbol and another imports it, each definition and their interaction will behave as described by the ABI, regardless of the rules of the language of the code that imports or exports the symbols.

Other implementations, especially those using Whole Program optimization, may treat symbols which are exported from one C compilation unit and used by another in a fashion different from what the ABI would suggest, especially if doing so would allow things to be more efficient, or allow a build system to produce better diagnostics.

Because both approaches have substantial advantages and disadvantages, the Standard is agnostic as to how implementations handle the interactions between functions in different modules. If a platform ABI happens to define a behavior, and a C implementation documents that C modules interact in the fashion defined by the ABI, then behavior would be defined on that implementation regardless of whether the Standard imposes any requirements. In other cases where the Standard imposes no requirements, anything could happen.

like image 29
supercat Avatar answered Nov 11 '22 14:11

supercat