Re: Banks and economy



s_dubrovich@xxxxxxxxx wrote:
[An awful lot of badly trimmed and confusing discussion]

If you want a comp.lang.c answer, you'll need to clarify what the issues being discussed actually are. It would help if you had told us what forum this thread was transferred from, so that we could trace the history of the earlier discussion.

First of all, and most importantly, the issue seems to be at least partly about K&R C, prior to it's first standardization. I think it's pretty pointless to ask any questions at this level of detail about K&R C. Prior to standardization, C was not a single coherent language, it was many different languages, each with it's own subtle (and in some cases, major) differences from the others. Questions about what it meant should be of purely historical interest - unless, of course, you're trying to cope with some legacy code written prior to standardization. In that case, I can give you my most profound sympathy, but no useful advice.

If the context of this discussion were at least advanced to C90, it would become feasible to meaningfully discuss the issues. Unfortunately, I could not address those issue in any detail, because I don't have a copy of the C90 standard; it was too expensive when I needed it, and I was more interested in C99 than C90 by the time the price dropped (and my salary rose) to the point where I could afford to buy a copy of C90.

Secondly, this seems to be about the difference between

char *cptr;

and

char cptr[];

Thirdly, this seems to be about the difference in meaning of those declarations when they appear in the parameter list of a non-prototyped function definition, and when they appear at file scope. I'm assuming that it's a non-prototyped function, because otherwise the ';' wouldn't be allowed. I'm assuming that it's at file scope, because otherwise the array declaration wouldn't be allowed.

I can give you C99 answers that I think are not significantly different from those in C90, but I can't be at all sure they are the same as would apply to pre-standard C.

Without having any declared size, the array declaration of cptr has an incomplete type.

This would seem to be a problem, because 6.7p7 and 6.7.5.3p4 both require such declarations to be complete. However, 6.7.5.3p7 says "A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’ ...", which is a complete type, and 6.7p7 and 6.7.5.3p4 both explicitly say that the requirement for completeness applies only after such adjustment. Thus, in a parameter list both declarations are equivalent. They're also equivalent to char cptr[255];, a fact which can be confusing if you're expecting sizeof(cptr) to be 255 rather than sizeof(char*).

Section 6.7.5.3p4 applies only to parameter lists in function definitions, and 6.7p7 doesn't apply to file scope declarations because they always have linkage. Therefore, the incomplete array declaration is a potential problem, but a solvable one.

Since it has file scope, no initializer, and no storage-class specifier, it counts as a tentative definition (6.9.2p2). In some cases, a tentative definition with no corresponding external definition ends up being treated as the actual definition, with an implicit initializer of 0. However, that's not possible for a tentative definition of an object with an incomplete type; the compiler doesn't have enough information to know how much space to set aside for it. Therefore, an incomplete tentative definition must be followed by another declaration of the same identifier, which has at least one of the following features:

a) it defines the identifier as having a compatible complete type:

char cptr[255];

b) it declares the identifier to be 'extern', indicating that the actual definition of the identifier, which must have a compatible complete type, might be found in some other translation unit:

extern char cptr[];

Regardless of which approach you use, at file scope

char cptr[];

tentatively defines cptr as an array of char, with the actual definition of that array to be provided elsewhere, while

char *cptr;

defines cptr to be a pointer to char.
.



Relevant Pages

  • Re: Banks and economy
    ... the incomplete array declaration is ... it counts as a tentative definition. ... but using the size (e.g. sizeof cptr) ... array of 1 of any type, here char. ...
    (comp.lang.c)
  • Re: MFC dll and exe porting to 64-bit
    ... Why the obsolete 'char *' instead of the proper LPTSTR? ... We are no longer programming 16-bit windows in an 8-bit character world, ... string arguments should probably be LPCTSTR, that is, const parameters. ... declaration of the function itself, in context (meaning show the surrounding class ...
    (microsoft.public.vc.mfc)
  • Re: malloc warning gcc > 4.0
    ... > char* p; ... > warning: incompatible implicit declaration of built-in function 'malloc' ...
    (comp.lang.c.moderated)
  • Re: Access one character in an array of characters
    ... enum Suit; ... Without seeing the exact declaration of ClubArray I cannot be certain, ... but you have probably declared it as a C-style string, ... confusion between a string and a vector of char. ...
    (alt.comp.lang.learn.c-cpp)
  • Re: Is it declaration or defination?
    ... Mark McIntyre writes: ... Its a declaration and a tentative definition, which will become a firm ... It could only be a tentative definition if it were at file scope. ...
    (comp.lang.c)