Re: suspicious error 'static declaration follows non-static declaration'

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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
> >>
> >>
> 





[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux