vic@grep.co.uk (Victor Gavin) (04/24/91)
I (after many, many years of C programming) found that I couldn't perform what I considered to be a reasonable assignment command. I traced it back to my use of char *fred = "bert" being the same as char fred[] = {'b', 'e', 'r', 't', '\0'} Which made me believe that I could use the following code: struct bert { int a, b; } struct fred { struct bert *abc; } blip = { {1,1} }; [[ie That the compiler will place the data for the structure into one of the data segments and then place it's address into the pointer variable.]] Of course none of my compilers liked this. Could anyone tell me whether the ANSI committee pondered over the problem of tidying up the inconsistencies of the C initializations ? vic -- Victor Gavin <vic@grep.co.uk||..!ukc!grep!vic||..!ukc!vision!grep!vic>
worley@compass.com (Dale Worley) (04/25/91)
In article <1991Apr24.141206.18103@grep.co.uk> vic@grep.co.uk (Victor Gavin) writes:
I traced it back to my use of
char *fred = "bert"
Could anyone tell me whether the ANSI committee pondered over the problem of
tidying up the inconsistencies of the C initializations ?
Actually, initializations *are* consistent -- other than the object
named in the declaration, an initialization *never* allocates memory.
What is allocating the "extra" memory is the string literal "bert".
String literals *always* allocate memory for themselves, except in the
special case when they are used as the initializer for an array of
chars. For instance,
char *p;
p = "1234";
allocates 5 bytes of memory to hold the string literal.
Dale Worley Compass, Inc. worley@compass.com
--
So you want to have a shameful affair?
Yet, somehow you can't justify it?
The next time you are contemplating a decision in which you are debating
whether or not to go for the gusto, ask yourself this Important Question:
How long will I be dead?
With that perspective, you can now make a free, fearless choice to do
just about any goddamned sneaky thing your devious little mind can think
up. Go ahead. Have your fun. You're welcome. Go on. See you in
Hell.
--Matt Groening
steve@taumet.com (Stephen Clamage) (04/26/91)
vic@grep.co.uk (Victor Gavin) writes: >... Which made me believe that I could use the following code: > struct bert { int a, b; } > struct fred { struct bert *abc; } blip = { {1,1} }; >[[ie That the compiler will place the data for the structure into one of the >data segments and then place it's address into the pointer variable.]] >Could anyone tell me whether the ANSI committee pondered over the problem of >tidying up the inconsistencies of the C initializations ? IMHO, this is not an inconsistency. There is no way to specify an anonymous aggregate constant in C. Further, if we accept the syntax you show, it would have to try to assign the aggregate constant to a pointer, which would be rejected in any case. You would need something more like this: struct fred { struct bert *abc; } blip = { &{1,1} }; This has some problems, in that {1, 1} has no type. Bracketed initializers are syntactic ways to supply values to members of the aggregate being initialized. "{1,1}" has no meaning on its own. You would need to extend the C language to support anonymous aggregate constants, perhaps along the lines of (struct bert){1, 1} (This is not a recommendation.) I don't know whether X3J11 ever discussed such a thing, but I'm sure they would have considered it outside their purview, there being no such existing practice. BTW, if one struct is "bert", shouldn't the other be "ernie"? -- Steve Clamage, TauMetric Corp, steve@taumet.com
jackm@agcsun.UUCP (Jack Morrison) (04/26/91)
In article <1991Apr24.141206.18103@grep.co.uk> vic@grep.co.uk (Victor Gavin) writes: >I (after many, many years of C programming) found that I couldn't perform what >I considered to be a reasonable assignment command. >I traced it back to my use of > char *fred = "bert" >being the same as > char fred[] = {'b', 'e', 'r', 't', '\0'} We'll assume ;-) you really meant that it's similar to char _fred[] = {'b', 'e', 'r', 't', '\0'}; char *fred = _fred; >Which made me believe that I could use the following code: > struct bert { int a, b; } > struct fred { struct bert *abc; } blip = { {1,1} }; > >[[ie That the compiler will place the data for the structure into one of the >data segments and then place it's address into the pointer variable.]] >Of course none of my compilers liked this. It's not so much an *initialization* inconsistency, but the limitation that you can't write a constant structure value the same way you can a constant string. For example, it would also be nice to be able to call void foo(struct bert b); [NOT "struct bert *b", mind you] as foo( {1,1} ); or, if the compiler would like a little more help, foo( (struct bert){1,1} ); I have no answer as to whether anyone official has considered it before... -- "How am I typing? Call 1-303-279-1300" Jack C. Morrison Ampex Video Systems 581 Conference Place, Golden CO 80401
gwyn@smoke.brl.mil (Doug Gwyn) (04/26/91)
In article <1991Apr24.141206.18103@grep.co.uk> vic@grep.co.uk (Victor Gavin) writes: >Could anyone tell me whether the ANSI committee pondered over the problem of >tidying up the inconsistencies of the C initializations ? I doubt that we would have considered proposals for changing those long-established parts of the C language that you described, for any longer than it would take to unanimously reject them. The charter of X3J11 did not include redesigning the language, rather merely standardizing existing practice and addressing perceived significant deficiencies. Well-established existing correct practice had to continue to be permitted.
chap@art-sy.detroit.mi.us (j chapman flack) (04/26/91)
In article <1991Apr24.141206.18103@grep.co.uk> vic@grep.co.uk (Victor Gavin) writes: > ... >I traced it back to my use of > char *fred = "bert" >being the same as > char fred[] = {'b', 'e', 'r', 't', '\0'} Ah, but they're not the same. You can tell by the result of sizeof fred in both cases. What the first is really (more or less) equivalent to is: char bill[] = {'b','e','r','t','\0'}; char *fred = bill; /* == &(bill[0]) */ It works because "bert" is one of the few types of constant defined into the C language (i.e., decimal, octal, hex, character, string, that's it). As a constant, "bert" is a character array in its own right; it can be used to initialize a character array, as in char fred[] = "bert"; /* which *is* the same as char fred[]={'b','e',...} */ or its address can be taken and used to initialize a char pointer, which happens implicitly in char *fred = "bert"; > >Which made me believe that I could use the following code: > > struct bert { int a, b; } > struct fred { struct bert *abc; } blip = { {1,1} }; > The difference is that the C definition doesn't build in a "structure constant". {1,1} is not a structure in its own right the way "garbonzo" is a character array in its own right. How could it be?--{1,1} doesn't contain enough information to create a finished struct declaration. So you can't just take the address of {1,1} as you could "garbonzo". You would need the form: struct bert { int a, b; } bill = {1,1}; struct fred { struct bert *abc } blip = { &bill }; I hope this helps. I don't think the problem is an inconsistency in C, it's just a consequence of C's lack of a "structure constant." If you wanted to add such a thing to the langauge, you'd have to define a syntax that included everything needed to declare an appropriate structure, such as element names, in the constant. I think that would add unnecessary complexity to the langauge. -- Chap Flack Their tanks will rust. Our songs will last. chap@art-sy.detroit.mi.us -Mikos Theodorakis Nothing I say represents Appropriate Roles for Technology unless I say it does.
jamshid@ut-emx.uucp (Jamshid Afshar) (04/27/91)
In article <959@agcsun.UUCP> jackm@agcsun.UUCP (Jack Morrison) writes: >In article <1991Apr24.141206.18103@grep.co.uk> vic@grep.co.uk (Victor Gavin) writes: ... >>Which made me believe that I could use the following code: >> struct bert { int a, b; } >> struct fred { struct bert *abc; } blip = { {1,1} }; ... >It's not so much an *initialization* inconsistency, but the limitation that >you can't write a constant structure value the same way you can a constant >string. For example, it would also be nice to be able to call > > void foo(struct bert b); > > foo( {1,1} ); >or, if the compiler would like a little more help, > foo( (struct bert){1,1} ); I just thought I'd mention that this kind of structure-on-the-fly stuff is possible in C++. struct bert { int a, b; bert(int the_a, int the_b) : a(the_a), b(the_b) {} }; foo( bert b ); // you don't need the keyword 'struct' ... foo( bert(5, 6) ); // call foo() with temporary bert Yes, it's a temporary created on the stack, but you can make a static object: static bert a_bert = bert(5, 6); or static bert a_bert(5, 6); // these two definitions are equivalent But, as Jack said, you can't write a constant structure value the same way you can a constant string in C or C++ (can't gcc do something like this, though?). Therefore, there is no way to do what Victor wanted to do without another variable. Anyway, I think every C programmer should take a look at C++, even if she or he doesn't do object-oriented programming (though I have found OOP to be a Very Good Thing). C++ removes alot of restrictions on initializations, has type-safe i/o (doesn't use var. args), is more strongly typed, has type-safe linkage, and IMO is just a better C. An ANSI C program should compile without any changes (except C++ requires a cast when assigning a void pointer to a typed pointer). Just another cog in the wheel of the OOP propaganda machine, :) Jamshid Afshar jamshid@emx.utexas.edu