On Sun, Feb 18, 2018 at 10:44 AM, Andrew Makhorin <mao@xxxxxxx> wrote: > 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. [...] >> [1] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf [...] > Thank you for your comments. My pleasure. > 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. The TC only drops the requirement that the prior visible declaration has a file scope. > Probably this change simplifies one-pass compilation. I think it is about fixing a conceptual bug given the following example: extern int i; // external linkage int f() { static int i; // internal linkage { extern int i; // external linkage before the change, internal linkage after the change } } I think the conceptual bug is because people expect the innermost i to follow the i whose enclosing scope is most immediate. > However, it is > still unclear to me why gcc produces an error rather than a warning, The definition of an undefined behavior I quoted in the previous e-mail says that it is okay for a compiler to terminate a translation with the issuance of a diagnostic message. > 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. Then, you have to argue for the merit of your particular case with GCC maintainers. The easiest perhaps is by filing a bug in GCC bugzilla. > Best regards, > > Andrew Makhorin -- Best regards, Tadeus