non conformance?

B

borophyll

The following code:

#include <stdio.h>
static int i[];

int main()
{
printf("%d\n",i[0]);
}

compiles fine but does not link. I would have thought that this would
not compile, since in the standard:

"If the declaration of an identifier for an object is a tentative
definition and has internal
linkage, the declared type shall not be an incomplete type."

I believe that i fits all the above conditions, and is an incomplete
type. Should this program not compile (hence a conformance issue with
gcc), or am I wrong/missing something, etc

regards,
B
 
J

Jack Klein

The following code:

#include <stdio.h>
static int i[];

int main()
{
printf("%d\n",i[0]);
}

compiles fine but does not link. I would have thought that this would
not compile, since in the standard:

You thought wrong. Who told you that a compiler is *ever* required
not to compile? Up until C99, there was never a requirement that an
implementation refuse to compile a translation unit, regardless of
what it contained.

Since C99, a compiler is prohibited from successfully translating a
program containing a #error preprocessor directive, unless this
directive itself is part of a group skipped by conditional
compilation.

Other than that, a translator may translate and generate an executable
from anything you hand it.
"If the declaration of an identifier for an object is a tentative
definition and has internal
linkage, the declared type shall not be an incomplete type."

Your program violates a "shall" in the standard that happens to be in
a "semantics" section, and not in a "constraints" section. That means
that your program generates undefined behavior and no requirements at
all are placed on the implementation. No diagnostic is required.

If your program violated a "shall" in a constraints section of the
standard, the compiler would be required to issue a diagnostic. But
that does not mean it could not also produce an executable, and the
behavior would still be undefined.
I believe that i fits all the above conditions, and is an incomplete
type. Should this program not compile (hence a conformance issue with
gcc), or am I wrong/missing something, etc

gcc, by default, is not a C compiler, but a compiler for a language
often referred to as "gnu C". That's not really a terrible fault, as
most compilers do not translate in their best standard conforming mode
by default.

Check your compiler documentation or post in a gcc newsgroup to find
out what options you should invoke your compiler with to get it to
issue a diagnostic for this situation, it is probably possible.

But get over the notion that you can write code that "should not
compiler". Other than the #error directive in C99 or later
conformance, a compiler is never forbidden from producing an
executable.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
F

Flash Gordon

Jack Klein wrote, On 11/09/07 02:39:
The following code:

#include <stdio.h>
static int i[];

int main()
{
printf("%d\n",i[0]);
}

compiles fine but does not link. I would have thought that this would
not compile, since in the standard:

Other than that, a translator may translate and generate an executable
from anything you hand it.


Your program violates a "shall" in the standard that happens to be in
a "semantics" section, and not in a "constraints" section. That means
that your program generates undefined behavior and no requirements at
all are placed on the implementation.

It seems odd to me that this is not in a constraints section since I
would have thought it something easy for a compiler to detect and report
at the end of compilation.
No diagnostic is required.

<snip more good stuff>

However, since the program refused to link, presumably with an error
message, the implementation *did* produce a diagnostic, just in a later
phase.
 
B

borophyll

The following code:
#include <stdio.h>
static int i[];
int main()
{
printf("%d\n",i[0]);
}
compiles fine but does not link. I would have thought that this would
not compile, since in the standard:

You thought wrong....

ok ok, point taken, but a more interesting question is why this clause
exists for internally linked object only. If you remove the static
keyword it is well defined behaviour. Why the prejudice against
internally linked objects?
 
B

Bart van Ingen Schenau

The following code:
#include <stdio.h>
static int i[];
int main()
{
printf("%d\n",i[0]);
}
compiles fine but does not link. I would have thought that this
would not compile, since in the standard:

You thought wrong....

ok ok, point taken, but a more interesting question is why this clause
exists for internally linked object only. If you remove the static
keyword it is well defined behaviour. Why the prejudice against
internally linked objects?

An object with internal linkage is only visible in the current
translation unit (TU)[1]. Therefor, the definition of such an object
must also be in that same TU and a definition always requires a
complete type.

If the object has external linkage, then there might be some other TU
that provides a definition for the object. If this other TU is not
present, then you violate another rule of the standard, the One
Definition Rule (ODR), which says that for each identifier with
external linkage, there must be exactly one definition. (No diagnostic
required).

Bart v Ingen Schenau

[1] Equivalent to a source file and all headers included.
 
C

Christopher Benson-Manica

[comp.lang.c] Jack Klein said:
Check your compiler documentation or post in a gcc newsgroup

I know the standard response is "post in a newsgroup devoted to X for
help with X", but in the case of gcc it turns out that the newsgroups
are generally much less active (and thus helpful) than the mailing
lists. I recommend http://gcc.gnu.org/lists.html to the OP, and I
recommend that gcc questions be referred to the mailing lists rather
than to the newsgroups.
 
J

Jack Klein

The following code:

#include <stdio.h>
static int i[];

int main()
{
printf("%d\n",i[0]);
}

compiles fine but does not link. I would have thought that this
would not compile, since in the standard:

You thought wrong....

ok ok, point taken, but a more interesting question is why this clause
exists for internally linked object only. If you remove the static
keyword it is well defined behaviour. Why the prejudice against
internally linked objects?

An object with internal linkage is only visible in the current
translation unit (TU)[1]. Therefor, the definition of such an object
must also be in that same TU and a definition always requires a
complete type.

OK, so far, so good.
If the object has external linkage, then there might be some other TU
that provides a definition for the object. If this other TU is not
present, then you violate another rule of the standard, the One
Definition Rule (ODR), which says that for each identifier with
external linkage, there must be exactly one definition. (No diagnostic
required).

Now you've lost me, for several reasons. First, C doesn't have the
C++ highly emphasized (with initial capital letters) "One Definition
Rule". Second, the possibility of an additional external definition
in another TU directly contradicts the feature of tentative
definitions.

A tentative definition of an object with external linkage in a C TU is
translated, by the compiler, into an complete definition with the
equivalent of "= {0};" for initialization at the end of the TU if no
non-tentative definition is found.

So once a tentative external definition is processed in a TU, any
other external definition for the identifier in another TU in the same
program produces undefined behavior.

The actual standard requirements for external definitions and
declarations in C is not called the "ODR" and states:

"An external definition is an external declaration that is also a
definition of a function (other than an inline definition) or an
object. If an identifier declared with external linkage is used in an
expression (other than as part of the operand of a sizeof operator
whose result is an integer constant), somewhere in the entire program
there shall be exactly one external definition for the identifier;
otherwise, there shall be no more than one."
Bart v Ingen Schenau

Please start adding proper signature delimiters to your posts.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
B

Bart van Ingen Schenau

Jack said:
Now you've lost me, for several reasons. First, C doesn't have the
C++ highly emphasized (with initial capital letters) "One Definition
Rule".

Ok, the C standard does not use the term ODR and does not have the same
restrictions as the C++ ODR.
I still find it a useful shorthand for the requirement stated in clause
6.9/5, even if the actual requirements for C are weaker than the
requirements for the C++ ODR.
The possibility to have multiple tentative definitions for an object is
not something that I would use or advocate.
Second, the possibility of an additional external definition
in another TU directly contradicts the feature of tentative
definitions.

This does not make sense to me. A valid program can not have an external
definition of object A in TU 1 and a tentative definition of object A
in TU 2.
If a TU contains a tentative definition of an object, then either the TU
also contains an external definition of that object, or the compiler
generates an external definition on reaching the end of the TU.
So, for all practical purposes, if you have a tentative definition in a
TU, then that TU will also provide the external definition.

Please start adding proper signature delimiters to your posts.
Can you indicate in which way my signature delimiter (dash, dash, space,
newline) is incorrect?
Note that I don't consider my name to be part of my signature.

Bart v Ingen Schenau
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,479
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top