On Sun, 2018-02-18 at 04:50 +0100, Tadeus Prastowo wrote: > Hi, > > After perusing the draft of C99 [1], which is the closest to the > default -std in GCC 4.7.2 (I believe the default is C90), I think your > code does not compile because it has an undefined behavior, which > according to section 3.4.3 paragraph 2 can result in a compilation > error. To quote the said paragraph, possible undefined behavior > ranges from ignoring the situation completely with unpredictable > results, to behaving during translation or program execution in a > documented manner characteristic of the environment (with or without > the issuance of a diagnostic message), to terminating a translation or > execution (with the issuance of a diagnostic message). End quote. > > The undefined behavior is due to function bar having both an external > linkage as per section 6.2.2 paragraph 4 and an internal linkage as > per section 6.2.2 paragraph 3. To quote section 6.2.2 paragraph 7, > if, within a translation unit, the same identifier appears with both > internal and external linkage, the behavior is undefined. End quote. > > [1] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf > > -- > Best regards, > Tadeus Thank you for your comments. You are right. I found the answer in Normative Changes to ISO/IEC 9899:1990 (Technical Corrigendum 1). In subclause 6.1.2.2, page 21, change: If the declaration of an identifier for an object or a function contains the storage-class specifier extern, the identifier has the same linkage as any visible declaration of the identifier with file scope. If there is no visible declaration with file scope, the identifier has external linkage. to: For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, if the prior declaration specifies internal or external linkage, the linkage of the identifier at the latter declaration becomes the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage. Probably this change simplifies one-pass compilation. However, it is still unclear to me why gcc produces an error rather than a warning, and there exists no option to change this compiler behavior. In many other cases that are forbidden by the Standard (e.g. if a pointer to char is implicitly converted to a pointer to int) gcc is more tolerant to provide portability for old codes. I think my case is similar. Best regards, Andrew Makhorin > > > On Fri, Feb 16, 2018 at 4:14 PM, Tadeus Prastowo > <tadeus.prastowo@xxxxxxxx> wrote: > > Hi, > > > > I think you are referring to C89 standard. Newer version of GCC might > > have switched to newer version of the C standard. So, try to compile > > your code with -std=c89? > > > > -- > > Best regards, > > Tadeus > > > > > > On Fri, Feb 16, 2018 at 3:41 PM, Andrew Makhorin <mao@xxxxxxx> wrote: > >> Hello, > >> > >> On compiling the following code with gcc (Debian 4.7.2-5) 4.7.2: > >> > >> int foo(int x, int y) > >> { > >> extern int bar(); > >> return bar(x, y); > >> } > >> > >> static int bar(int x, int y) > >> { > >> return x + y; > >> } > >> > >> I get the following error: > >> > >> mao@corvax:~/Desktop$ gcc -c test.c > >> test.c:7:15: error: static declaration of 'bar' follows non-static > >> declaration > >> test.c:3:21: note: previous declaration of 'bar' was here > >> > >> However, the Standard says [6.1.2.2 Linkages of identifiers]: > >> > >> If the declaration of an identifier for an object or a function > >> contains the storage-class specifier extern, the identifier has the > >> same linkage as any visible declaration of the identifier with file > >> scope. > >> > >> There is no other way to declare 'bar' as static in block scope, > >> because it is a function, so this error confuses me. Could anyone > >> explain this? Should it be a warning rather than error? I'd like to note > >> that my code is compiled successfully with older versions of gcc and > >> with many other C compilers. > >> > >> > >> Thanks, > >> > >> Andrew Makhorin > >> > >> >