Text processing

A

Alan Curry

Yes, it's very odd. I assume there is some advantage in knowing the
complete type of objects with internal linkage at the get go. I can't
think of one, though.

I asked about this recently (good luck finding the thread on DejaGoo)
and the conclusion was that static int foo[] was originally forbidden
because classic single-pass compilers didn't support it. (The linker would
take care of resolving the non-static equivalent.) It remains forbidden in
the standard because nobody on the committee noticed it and cared enough to
formally propose removing it.
 
H

Harald van Dijk

Yes, it's very odd.  I assume there is some advantage in knowing the
complete type of objects with internal linkage at the get go.  I can't
think of one, though.

I asked about this recently (good luck finding the thread on DejaGoo)
and the conclusion was that static int foo[] was originally forbidden
because classic single-pass compilers didn't support it. (The linker would
take care of resolving the non-static equivalent.) It remains forbidden in
the standard because nobody on the committee noticed it and cared enough to
formally propose removing it.

Ah, thank you, that actually makes sense.
 
B

Ben Bacarisse

Harald van Dijk said:
Harald van Dijk said:
However, I don't think 6.9.2p3 makes much sense if the final composite
type is assumed to be the intended meaning because, I don't think the
final composite type *can* be incomplete?  For example, a translation
union with nothing other than
  int array[];
is fine and causes the type of array to be int [1] by at the end.
I was thinking of incomplete structure and union types.

I'd considered that and ruled them out.  Composite types must be
compatible, and an incomplete struct type is not compatible with a
complete one declared in the same translation unit (I think!).

An incomplete struct type is completed by a struct definition with the
same tag in the same scope, see 6.7.2.3p4 for the official wording and
p12 for an example.

struct X x; /* tentative definition with incomplete type */
struct X { int a; }; /* completed here */

Right. I've now confused myself! What matters is types that remain
incomplete, not completed ones, because the question was whether the
type referred to in 6.9.2 p3 (the one that must not be incomplete) is in
fact the composite type referred to in the previous paragraph. (We know
it isn't, but that was the speculation -- was that the intended
meaning).

We know that one or more tentative definitions of an array do not yield
an incomplete composite type -- the implied = {0} makes it an array of
length one. What happens with structs? Can the composite type remain
incomplete? I don't think so.

Somewhat separately, I need to ask you about your citations because
6.7.2.3 p12 does not have an example of a tentative definition. All I
can see is a forward declaration of the tag. And 6.7.2.3 p4 just says
when a struct declaration becomes complete. It does not say anything
about one or more tentative definitions and the final composite type
that results from them. In other words, I can't reconcile your example
with 6.9.2 p2. As you have it, there is only the one tentative
definition with an incomplete type. I presume that you would say that
the composite type is the complete struct because the type as been
completed by the end of the translation unit. But what about the slight
variant:

struct X x; /* tentative definition with incomplete type */
struct X { int a; } x; /* another one that also completes the type */

I can't find the wording the says these two struct types are compatible.
 
J

James Kuyper

On 09/26/2011 05:58 PM, Ben Bacarisse wrote:
....
However, I don't think 6.9.2p3 makes much sense if the final composite
type is assumed to be the intended meaning because, I don't think the
final composite type *can* be incomplete? For example, a translation
union with nothing other than

int array[];

is fine and causes the type of array to be int [1] by at the end.

Citation please? I'm not familiar with that feature, and I have not
managed to find any specification of it in the standard.
 
B

Ben Bacarisse

James Kuyper said:
On 09/26/2011 05:58 PM, Ben Bacarisse wrote:
...
However, I don't think 6.9.2p3 makes much sense if the final composite
type is assumed to be the intended meaning because, I don't think the
final composite type *can* be incomplete? For example, a translation
union with nothing other than

int array[];

is fine and causes the type of array to be int [1] by at the end.

Citation please? I'm not familiar with that feature, and I have not
managed to find any specification of it in the standard.

6.9.2 p2 and p5 for an example.
 
H

Harald van Dijk

We know that one or more tentative definitions of an array do not yield
an incomplete composite type -- the implied = {0} makes it an array of
length one.  What happens with structs?  Can the composite type remain
incomplete?  I don't think so.

If the composite type remains incomplete, then the implied = {0} is an
invalid initializer, so the composite type cannot remain incomplete in
a valid program. I'm not sure if I'm understanding you right:

extern struct never_defined x; /* no tentative definition, valid */
struct never_defined y; /* tentative definition, invalid if struct is
never defined */
Somewhat separately, I need to ask you about your citations because
6.7.2.3 p12 does not have an example of a tentative definition.  All I
can see is a forward declaration of the tag.

Yes, it was merely an example of an incomplete struct being completed.
 And 6.7.2.3 p4 just says
when a struct declaration becomes complete.  It does not say anything
about one or more tentative definitions and the final composite type
that results from them.

What p4 says is that

struct X; /* 1 */
struct X x; /* a */
struct X { int a; }; /* 2 */
struct X x; /* b */

lines 1 and 2 declare the *same* type. Because of that, there is no
question of what the composite type of tentative definitions a and b
is, because the type is identical: it is struct X.
 In other words, I can't reconcile your example
with 6.9.2 p2.  As you have it, there is only the one tentative
definition with an incomplete type.  I presume that you would say that
the composite type is the complete struct because the type as been
completed by the end of the translation unit.  But what about the slight
variant:

  struct X x; /* tentative definition with incomplete type */
  struct X { int a; } x; /* another one that also completes the type  */

I can't find the wording the says these two struct types are compatible.

To be slightly more thorough: 6.2.7 starts with
"Two types have compatible type if their types are the same."
 
B

Ben Bacarisse

Harald van Dijk said:
If the composite type remains incomplete, then the implied = {0} is an
invalid initializer, so the composite type cannot remain incomplete in
a valid program. I'm not sure if I'm understanding you right:

extern struct never_defined x; /* no tentative definition, valid */
struct never_defined y; /* tentative definition, invalid if struct is
never defined */

Yes, I think we are on the same page. The point I was trying to make
(and got all messed up) was that either the composite type ends up
complete because of the implied initialiser (for arrays) or the program
is invalid because the composite type remains incomplete. (I said
"can't be incomplete" which is ambiguous at best -- I meant "can't be
incomplete in a valid program".)

The reason for making that point is now entirely redundant since
everyone agrees that 6.9.2. p3 is making a special exception motivated
by concern for limited compiler abilities.
Yes, it was merely an example of an incomplete struct being completed.


What p4 says is that

struct X; /* 1 */
struct X x; /* a */
struct X { int a; }; /* 2 */
struct X x; /* b */

lines 1 and 2 declare the *same* type. Because of that, there is no
question of what the composite type of tentative definitions a and b
is, because the type is identical: it is struct X.


To be slightly more thorough: 6.2.7 starts with
"Two types have compatible type if their types are the same."

Sometimes (often?) I miss the obvious. By concentrating on the
completion of the type, I missed that fact p4 makea the types
the same so of course they are compatible.
 
T

Tim Rentsch

Harald van Dijk said:
And, second, the
output does not compile because the initial
static char *StringTable[];
is a tentative definition of an object with incomplete type (that's a
constraint violation).

6.9.2p3 says the declared type of a tentative definition with internal
linkage must not be an incomplete type, but it isn't a constraint,
which matters because it means compilers are not required to issue any
diagnostics. And I wonder if that is really meant to apply to the
declared type, rather than the composite type for the final implicit
definition mentioned in p2. Compilers are already required to accept
"int array[]; int array[20] = {1};" -- without the static keyword --
and they would surely need to treat the static keyword specially to
reject it if present.

I feel I should add that the standard does clearly and unambiguously
disallow this, [snip]

A more accurate statement is that the Standard clearly
and unambiguously allows it. The construct isn't
required to work portably (or at all), but it is
allowed - any implementation is free to accept it
and treat it as most people would expect.
 
H

hormelfree

Another counter-example is that many older dialects of BASIC *didn't*
store their programs as text files, but used a tokenised format for the
sake of space and performance.

I think that was called "Java(TM)"...
 
K

Keith Thompson

I think that was called "Java(TM)"...

I didn't see a smiley, so ...

No, that's not the same thing at all.

Java source code is text. It's typically *compiled* to byte code,
referred to as "Java bytecode". Other languages can be, and are,
compiled to the same byte code used by Java implementations, and
Java source can be compiled to things other than Java bytecode.

What "Nobody" is referring to is that there have been implementations
of BASIC where the program *source*, though it might be displayed as
text, is never actually stored as text. For example, the keyword
"GOSUB" would not be stored as the 5 characters 'G', 'O', 'S',
'U', 'B', but as a single encoded byte (that's displayed as "GOSUB"
by the specialized editor used to create and modify BASIC programs).
 

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,767
Messages
2,569,571
Members
45,045
Latest member
DRCM

Latest Threads

Top