 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Kenneth Brody Guest
|
Posted: Fri Jun 22, 2012 3:30 pm Post subject: C scope and struct definitions |
|
|
The discussion about scope in the "What a stupid gcc" thread reminded me of
the one time (that I recall) where I was bitten by this. I don't recall the
specifics, but it had to do with a function that was passed a pointer to a
struct, when there was no struct by that name visible.
Something like:
int foo(struct bar *);
...
int foo(struct bar *baz)
{
...
}
The compiler decided that the "struct bar" in one place was not the same
"struct bar" in the other place.
The solution, of course, was to add a simple "struct bar;" at file scope
prior to its first reference.
I can't duplicate any error right now, though a simple test does give me a
warning:
'bar' : named type definition in parentheses
Was the compiler correct to treat the two references as distinct? If a
struct definition is not visible at the time, can a reference to a pointer
to that struct be a different type than another one to the same named struct?
Again, I don't remember the exact details, as it was some time ago.
--
Kenneth Brody |
|
| Back to top |
|
 |
Eric Sosman Guest
|
Posted: Fri Jun 22, 2012 4:02 pm Post subject: Re: C scope and struct definitions |
|
|
On 6/22/2012 1:30 PM, Kenneth Brody wrote:
| Quote: | The discussion about scope in the "What a stupid gcc" thread reminded me
of the one time (that I recall) where I was bitten by this. I don't
recall the specifics, but it had to do with a function that was passed a
pointer to a struct, when there was no struct by that name visible.
Something like:
int foo(struct bar *);
...
int foo(struct bar *baz)
{
...
}
The compiler decided that the "struct bar" in one place was not the same
"struct bar" in the other place.
The solution, of course, was to add a simple "struct bar;" at file scope
prior to its first reference.
I can't duplicate any error right now, though a simple test does give me
a warning:
'bar' : named type definition in parentheses
Was the compiler correct to treat the two references as distinct? If a
struct definition is not visible at the time, can a reference to a
pointer to that struct be a different type than another one to the same
named struct?
Again, I don't remember the exact details, as it was some time ago.
|
The compiler was right. The relevant text is in 6.2.1p4:
"[...] If the declarator or type specifier that declares
the identifier appears inside a block or within the list
of parameter declarations in a function definition, the
identifier has block scope, which terminates at the end
of the associated block. If the declarator or type specifier
that declares the identifier appears within the list of
parameter declarations in a function prototype (not part
of a function definition), the identifier has function
prototype scope, which terminates at the end of the
function declarator. [...]"
So: The scope of `struct bar' in the first part of your example
ends where the prototype does (second sentence), while that of
`struct bar' in the second part is confined to the function body
(first sentence). The scopes do not overlap, so the two uses of
`struct bar' are distinct.
See also FAQ Question 11.5.
--
Eric Sosman
esosman@ieee-dot-org.invalid |
|
| Back to top |
|
 |
Ben Pfaff Guest
|
Posted: Fri Jun 22, 2012 8:47 pm Post subject: Re: C scope and struct definitions |
|
|
pacman (AT) kosh (DOT) dhis.org (Alan Curry) writes:
| Quote: | I don't even see why you'd ever want any scope for a struct type other than
"from here to the end of the file". Types are global things.
|
Occasionally I do declare and use a struct type within a
function. I'd like that to continue working.
I do agree that the behavior of struct types defined within a
function prototype is surprising and not useful. |
|
| Back to top |
|
 |
Eric Sosman Guest
|
Posted: Fri Jun 22, 2012 10:32 pm Post subject: Re: C scope and struct definitions |
|
|
On 6/22/2012 6:40 PM, Alan Curry wrote:
| Quote: | In article <js2buv$evv$1@dont-email.me>,
Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
On 6/22/2012 1:30 PM, Kenneth Brody wrote:
int foo(struct bar *);
...
int foo(struct bar *baz)
{
...
}
The compiler decided that the "struct bar" in one place was not the same
"struct bar" in the other place.
[...]
The compiler was right. The relevant text is in 6.2.1p4:
But is the compiler right for a real reason, or is it just a continuation of
a historical accident? Why would you ever want this behavior?
|
The Rationale sheds no light my tired old eyes can see. You
are welcome to read it for yourself. (Also, if you think the
normative text of the formal definition of the C language does not
qualify as "a real reason," well ...)
| Quote: | I don't even see why you'd ever want any scope for a struct type other than
"from here to the end of the file". Types are global things.
|
Say, what?
void f(void) {
static const struct foo {
const char *roman;
int decimal;
} table[] = { { "I", 1 }, { "II", 2 }, ... };
...
}
void g(void) {
struct foo {
double payload;
struct foo *next;
} *head, *p, *q;
...
}
Do you seriously maintain that these two `struct foo' types
should conflict with each other? If so, why? Explain why you
feel it is Wrong for a function to declare and use its own
private type for its own purposes, and why f() should have to
worry about what g() does in the privacy of its own block.
--
Eric Sosman
esosman@ieee-dot-org.invalid |
|
| Back to top |
|
 |
Alan Curry Guest
|
Posted: Fri Jun 22, 2012 10:40 pm Post subject: Re: C scope and struct definitions |
|
|
In article <js2buv$evv$1@dont-email.me>,
Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
| Quote: | On 6/22/2012 1:30 PM, Kenneth Brody wrote:
int foo(struct bar *);
...
int foo(struct bar *baz)
{
...
}
The compiler decided that the "struct bar" in one place was not the same
"struct bar" in the other place.
[...]
The compiler was right. The relevant text is in 6.2.1p4:
|
But is the compiler right for a real reason, or is it just a continuation of
a historical accident? Why would you ever want this behavior?
I don't even see why you'd ever want any scope for a struct type other than
"from here to the end of the file". Types are global things.
--
Alan Curry |
|
| Back to top |
|
 |
Keith Thompson Guest
|
Posted: Sat Jun 23, 2012 9:18 pm Post subject: Re: C scope and struct definitions |
|
|
pacman (AT) kosh (DOT) dhis.org (Alan Curry) writes:
| Quote: | In article <js32rk$siv$1@dont-email.me>,
Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
On 6/22/2012 6:40 PM, Alan Curry wrote:
But is the compiler right for a real reason, or is it just a
continuation of a historical accident? Why would you ever want this
behavior?
The Rationale sheds no light my tired old eyes can see. You
are welcome to read it for yourself. (Also, if you think the
normative text of the formal definition of the C language does not
qualify as "a real reason," well ...)
The standard was supposed to codify existing practice. A real reason
would have to come from before standardization. Was there a real
reason for the existence of such a small, useless scope?
|
Yes: it's not useless.
| Quote: |
I don't even see why you'd ever want any scope for a struct type other than
"from here to the end of the file". Types are global things.
Say, what?
void f(void) {
static const struct foo {
const char *roman;
int decimal;
} table[] = { { "I", 1 }, { "II", 2 }, ... };
...
}
void g(void) {
struct foo {
double payload;
struct foo *next;
} *head, *p, *q;
...
}
Do you seriously maintain that these two `struct foo' types
should conflict with each other? If so, why? Explain why you
feel it is Wrong for a function to declare and use its own
private type for its own purposes, and why f() should have to
worry about what g() does in the privacy of its own block.
I don't think we'd be losing anything if those declarations were simply
illegal. Declare your structs before your functions. They aren't variables.
|
We'd lose backward compatibility; it would break existing code. I've
seen plenty of small programs that define types inside main (or
would you make main a special case?).
Nothing stops you from declaring your structs at file scope if you
want to, and I agree that it's *usually* the best thing to do.
But if a given type happens to be used only inside one function,
or even inside one block, the language allows you to declare it
there without polluting the rest of the program's namespace.
| Quote: | A struct describes the procedure for interpreting bits in memory. As a
procedure description, it's more like a function than a variable. It doesn't
occupy memory itself, so it doesn't have a lifetime that can end when the
function call ends. Putting it inside the function gives you nothing.
|
We're talking about scope, not lifetime. Types don't have lifetime,
but like any other declared entity, they do have scope (the region
of source code over in they're visible).
The scope rules for types are consistent with the scope rules for
objects. This consistency makes the language simpler, and has no
real cost that I can see. Again, if you don't want to declare types
at block scope, then by all means don't.
[...]
--
Keith Thompson (The_Other_Keith) kst-u (AT) mib (DOT) org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister" |
|
| Back to top |
|
 |
Eric Sosman Guest
|
Posted: Sat Jun 23, 2012 9:54 pm Post subject: Re: C scope and struct definitions |
|
|
On 6/23/2012 6:06 PM, Alan Curry wrote:
| Quote: | In article <js32rk$siv$1@dont-email.me>,
Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
On 6/22/2012 6:40 PM, Alan Curry wrote:
But is the compiler right for a real reason, or is it just a continuation of
a historical accident? Why would you ever want this behavior?
The Rationale sheds no light my tired old eyes can see. You
are welcome to read it for yourself. (Also, if you think the
normative text of the formal definition of the C language does not
qualify as "a real reason," well ...)
The standard was supposed to codify existing practice. A real reason would
have to come from before standardization. Was there a real reason for the
existence of such a small, useless scope?
|
Note that existing practice had no notion of prototypes at all,
so the issue of "prototype scope" simply didn't exist. (The ANSI
Standard invented other things new to the language, too: `void',
for example.)
But once you've decided to declare a function with a prototype,
what scope should any identifiers in the prototype have? It seems
pretty clear you don't want them leaking outside, else
void foo(char *p);
void bar(double *p);
.... wouldn't compile, because of the conflicting declarations of `p'.
I suggest that would have been untenable.
A consequence of "What happens in prototype stays in prototype"
is that *all* in-prototype identifiers' scopes are limited to the
prototype itself. Yes, it leads to a useless construct -- but have
you got a usable alternative?
| Quote: |
I don't even see why you'd ever want any scope for a struct type other than
"from here to the end of the file". Types are global things.
Say, what?
void f(void) {
static const struct foo {
const char *roman;
int decimal;
} table[] = { { "I", 1 }, { "II", 2 }, ... };
...
}
void g(void) {
struct foo {
double payload;
struct foo *next;
} *head, *p, *q;
...
}
Do you seriously maintain that these two `struct foo' types
should conflict with each other? If so, why? Explain why you
feel it is Wrong for a function to declare and use its own
private type for its own purposes, and why f() should have to
worry about what g() does in the privacy of its own block.
I don't think we'd be losing anything if those declarations were simply
illegal. Declare your structs before your functions. They aren't variables.
|
I'm glad the Standard didn't take your view. While I'll admit
that function-specific types are not all that common, I'll maintain
that they are extremely useful. Most often, there's an ad-hoc
table of some kind to assist a function in the performance of its
work: Maybe an association of states with their capitols, or ranges
of `x' where a rational function/Chebyshev approximation/continued
fraction is the preferred computation method. Whatever it is, if
it's specific to the operation of one function I see *no* reason to
inflict it on others.
| Quote: | A struct describes the procedure for interpreting bits in memory. As a
procedure description, it's more like a function than a variable. It doesn't
occupy memory itself, so it doesn't have a lifetime that can end when the
function call ends. Putting it inside the function gives you nothing.
|
All the same statements could be made about an identifier of any
kind whatsoever. Should `x' leak out of one function into others?
| Quote: | If you really have two different structs with the same name in one program,
you should want to be warned about it. It's a sign that you should either
merge them (if they are different representations of the same concept) or
rename them.
|
Bah.
| Quote: | Variables, functions, and constant data are all defined with reference to
types. Types are the most fundamental entities in a program. They deserve
globally unique names.
|
I'm with you, up to the antepenultimate word. Why should a
type declared in the bowels of some function in some library I don't
even have source to be "global?" How shall I select my identifiers
to ensure that no third party's library bollixes them?
If you want "global," go back to BASICs. (By which I mean
Kemeny and Kurtz, not MS.)
--
Eric Sosman
esosman@ieee-dot-org.invalid |
|
| Back to top |
|
 |
Alan Curry Guest
|
Posted: Sat Jun 23, 2012 10:06 pm Post subject: Re: C scope and struct definitions |
|
|
In article <js32rk$siv$1@dont-email.me>,
Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
| Quote: | On 6/22/2012 6:40 PM, Alan Curry wrote:
But is the compiler right for a real reason, or is it just a continuation of
a historical accident? Why would you ever want this behavior?
The Rationale sheds no light my tired old eyes can see. You
are welcome to read it for yourself. (Also, if you think the
normative text of the formal definition of the C language does not
qualify as "a real reason," well ...)
|
The standard was supposed to codify existing practice. A real reason would
have to come from before standardization. Was there a real reason for the
existence of such a small, useless scope?
| Quote: |
I don't even see why you'd ever want any scope for a struct type other than
"from here to the end of the file". Types are global things.
Say, what?
void f(void) {
static const struct foo {
const char *roman;
int decimal;
} table[] = { { "I", 1 }, { "II", 2 }, ... };
...
}
void g(void) {
struct foo {
double payload;
struct foo *next;
} *head, *p, *q;
...
}
Do you seriously maintain that these two `struct foo' types
should conflict with each other? If so, why? Explain why you
feel it is Wrong for a function to declare and use its own
private type for its own purposes, and why f() should have to
worry about what g() does in the privacy of its own block.
|
I don't think we'd be losing anything if those declarations were simply
illegal. Declare your structs before your functions. They aren't variables.
A struct describes the procedure for interpreting bits in memory. As a
procedure description, it's more like a function than a variable. It doesn't
occupy memory itself, so it doesn't have a lifetime that can end when the
function call ends. Putting it inside the function gives you nothing.
If you really have two different structs with the same name in one program,
you should want to be warned about it. It's a sign that you should either
merge them (if they are different representations of the same concept) or
rename them.
Variables, functions, and constant data are all defined with reference to
types. Types are the most fundamental entities in a program. They deserve
globally unique names.
--
Alan Curry |
|
| Back to top |
|
 |
James Kuyper Guest
|
Posted: Sat Jun 23, 2012 10:57 pm Post subject: Re: C scope and struct definitions |
|
|
On 06/23/2012 07:54 PM, Eric Sosman wrote:
....
| Quote: | But once you've decided to declare a function with a prototype,
what scope should any identifiers in the prototype have? It seems
pretty clear you don't want them leaking outside, else
void foo(char *p);
void bar(double *p);
... wouldn't compile, because of the conflicting declarations of `p'.
I suggest that would have been untenable.
A consequence of "What happens in prototype stays in prototype"
is that *all* in-prototype identifiers' scopes are limited to the
prototype itself. Yes, it leads to a useless construct -- but have
you got a usable alternative?
|
Two:
C++ way: prohibit definition of types in there parameter list of a
function declaration.
Useful alternative: give types defined in a function's parameter list
the same scope as the function's declaration, rather than function
prototype scope.
....
| Quote: | I'm glad the Standard didn't take your view. While I'll admit
that function-specific types are not all that common, I'll maintain
that they are extremely useful. Most often, there's an ad-hoc
table of some kind to assist a function in the performance of its
work: Maybe an association of states with their capitols, or ranges
of `x' where a rational function/Chebyshev approximation/continued
fraction is the preferred computation method. Whatever it is, if
it's specific to the operation of one function I see *no* reason to
inflict it on others.
|
Agreed; for things declared inside of a function, that's entirely
reasonable. But for a type that's part of a function's interface, if the
identifier for that type has a scope is limited to the function body, no
other function can call it - which is rather limiting.
| Quote: | A struct describes the procedure for interpreting bits in memory. As a
procedure description, it's more like a function than a variable. It doesn't
occupy memory itself, so it doesn't have a lifetime that can end when the
function call ends. Putting it inside the function gives you nothing.
All the same statements could be made about an identifier of any
kind whatsoever. Should `x' leak out of one function into others?
|
No, only identifiers identifying types should leak out, only when they
are part of the parameter list.
--
James Kuyper |
|
| Back to top |
|
 |
Eric Sosman Guest
|
Posted: Sat Jun 23, 2012 11:48 pm Post subject: Re: C scope and struct definitions |
|
|
On 6/23/2012 8:56 PM, Alan Curry wrote:
| Quote: | In article <js5l0m$64l$1@dont-email.me>,
Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
[...]
But once you've decided to declare a function with a prototype,
what scope should any identifiers in the prototype have? It seems
pretty clear you don't want them leaking outside, else
void foo(char *p);
void bar(double *p);
... wouldn't compile, because of the conflicting declarations of `p'.
I suggest that would have been untenable.
Those names should simply be omitted, and it would be a good thing if they
weren't allowed either. They serve no purpose and cause problems in header
files when one header defines a macro that another header uses as an argument
name in a prototype.
We are allowed to use the intelligent comment markers /* */ in C, not just
the dumb // to-end-of-line kind, so you can say
void f(char * /*p*/, double * /*q*/);
if the parameter names are meant to be documentation.
|
So your argument against prototype scope boils down to "C's
syntax should be different." Okay, fine; tastes differ. But two
points stand out: First, that *given* the decision to allow
identifiers in prototypes, prototype scope follows as a practical
necessity. Second, that if identifiers were forbidden in prototypes,
then the entire thread would never have started in the first place
and so the whole argument evaporates.
| Quote: | Anyway, putting type names and variable names into a single category and
calling them "identifiers" is a false generalization.
|
If type names are somehow segregated from names-of-other-things,
does that mean
double int = 42;
long * double void(short long);
struct struct { long *union; char enum; };
.... are to your liking?
(In my early youth I was weaned on a language that had no
reserved words at all, a language in which `DO 10 I = (1 , 10)'
was perfectly legal and *not* a loop construct. For a while I
esteemed this as a sort of Purity. I got over it.)
But, hey: Back to the beginning. You asked whether a compiler
that obeyed 6.2.1p4 did so quote "for a real reason" end quote.
The answer to your question is "Yes," because 6.2.1p4 dictates
how the compiler must behave. Debate about whether 6.2.1p4 ought
to have said something else should be between you and X3J11, not
between you and me.
--
Eric Sosman
esosman@ieee-dot-org.invalid |
|
| Back to top |
|
 |
Eric Sosman Guest
|
Posted: Sun Jun 24, 2012 12:11 am Post subject: Re: C scope and struct definitions |
|
|
On 6/23/2012 8:57 PM, James Kuyper wrote:
| Quote: | On 06/23/2012 07:54 PM, Eric Sosman wrote:
[...]
A consequence of "What happens in prototype stays in prototype"
is that *all* in-prototype identifiers' scopes are limited to the
prototype itself. Yes, it leads to a useless construct -- but have
you got a usable alternative?
Two:
C++ way: prohibit definition of types in there parameter list of a
function declaration.
|
I'm not a C++ lawyer (nor even a C++ fluent speaker (although I
have "C++ Readability," go figure)), but "no type declarations in
function declarations" seems awfully restrictive:
int main(int argc, char **argv) // BZZZZT!
What must one do instead?
typedef char **charStarStar;
int main(int argc, charStarStar argv)
? But, as I say, I don't speak That Other Language, and maybe I've
read more into your synopsis than was actually present.
| Quote: | Useful alternative: give types defined in a function's parameter list
the same scope as the function's declaration, rather than function
prototype scope.
|
I'd worked up a nice reductio ad absurdum, and then realized that
you meant something other than what you'd said: You said "same scope
as the function's *declaration*," but you meant "same scope as the
function's *identifier*." I dunno: Might be reasonable, might have
unwelcome consequences in corner cases, might disable some corner
cases that are legitimate now but Ought To Be Banned (Just Think Of
The Children!), ... Needs more thought than my graying gray cells
can muster.
--
Eric Sosman
esosman@ieee-dot-org.invalid |
|
| Back to top |
|
 |
Keith Thompson Guest
|
Posted: Sun Jun 24, 2012 12:25 am Post subject: Re: C scope and struct definitions |
|
|
pacman (AT) kosh (DOT) dhis.org (Alan Curry) writes:
| Quote: | In article <js5l0m$64l$1@dont-email.me>,
Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
On 6/23/2012 6:06 PM, Alan Curry wrote:
In article <js32rk$siv$1@dont-email.me>,
Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
On 6/22/2012 6:40 PM, Alan Curry wrote:
But is the compiler right for a real reason, or is it just a
continuation of a historical accident? Why would you ever want
this behavior?
The Rationale sheds no light my tired old eyes can see. You
are welcome to read it for yourself. (Also, if you think the
normative text of the formal definition of the C language does not
qualify as "a real reason," well ...)
The standard was supposed to codify existing practice. A real reason
would have to come from before standardization. Was there a real
reason for the existence of such a small, useless scope?
Note that existing practice had no notion of prototypes at all,
so the issue of "prototype scope" simply didn't exist. (The ANSI
Standard invented other things new to the language, too: `void',
for example.)
But once you've decided to declare a function with a prototype,
what scope should any identifiers in the prototype have? It seems
pretty clear you don't want them leaking outside, else
void foo(char *p);
void bar(double *p);
... wouldn't compile, because of the conflicting declarations of `p'.
I suggest that would have been untenable.
Those names should simply be omitted, and it would be a good thing if they
weren't allowed either. They serve no purpose and cause problems in header
files when one header defines a macro that another header uses as an argument
name in a prototype.
We are allowed to use the intelligent comment markers /* */ in C, not just
the dumb // to-end-of-line kind, so you can say
void f(char * /*p*/, double * /*q*/);
if the parameter names are meant to be documentation.
|
Personally, I like having names for parameters in function declarations,
though I'm not pleased that they're ignored. My own preference would be
to make the names mandatory, and to require them to match the names used
in the function's definition.
So neither of is 100% satisfied with the way C is defined. I don't know
of anyone who is.
(I disagree with your characterization of // comments as "dumb", but I
won't get into that.)
| Quote: | Anyway, putting type names and variable names into a single category and
calling them "identifiers" is a false generalization. It works at the
technical level for the compiler implementor I guess, but besides that what's
the reason for lumping them together and insisting that they behave the same?
If you can't explain it without the word "identifier" then there is no
reason, it's just a thought process that's being misled by a bit of escaped
compiler-writer's jargon.
|
I'd say it's a perfectly valid generalization. They *are* both
identifiers, and they follow the same scope rules.
You advocate treating type names as a special case with different scope
rules than other identifiers. That's a valid preference, but not one
that I share -- and not one that's consistent with C as it's currently
defined.
| Quote: | I don't think we'd be losing anything if those declarations were simply
illegal. Declare your structs before your functions. They aren't variables.
I'm glad the Standard didn't take your view. While I'll admit
that function-specific types are not all that common, I'll maintain
that they are extremely useful. Most often, there's an ad-hoc
table of some kind to assist a function in the performance of its
work: Maybe an association of states with their capitols, or ranges
of `x' where a rational function/Chebyshev approximation/continued
fraction is the preferred computation method. Whatever it is, if
it's specific to the operation of one function I see *no* reason to
inflict it on others.
The same could be said for a function that's only called by one other
function. Should we have nested functions then?
|
Many languages do have nested functions. What tends to make them
complicated is the need to define rules for accessing objects defined
in an outer function. I wouldn't strongly object to adding nested
functions to C (and gcc supports them as an extension), but I don't
think they're all that important; we've gotten along without them
for a very long time.
[...]
| Quote: | Variable scopes make sense because the object named by the variable doesn't
exist until the function is called. A type isn't an object.
|
Are you conflating scope and lifetime?
[...]
--
Keith Thompson (The_Other_Keith) kst-u (AT) mib (DOT) org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister" |
|
| Back to top |
|
 |
James Kuyper Guest
|
Posted: Sun Jun 24, 2012 12:51 am Post subject: Re: C scope and struct definitions |
|
|
On 06/23/2012 10:11 PM, Eric Sosman wrote:
| Quote: | On 6/23/2012 8:57 PM, James Kuyper wrote:
On 06/23/2012 07:54 PM, Eric Sosman wrote:
[...]
A consequence of "What happens in prototype stays in prototype"
is that *all* in-prototype identifiers' scopes are limited to the
prototype itself. Yes, it leads to a useless construct -- but have
you got a usable alternative?
Two:
C++ way: prohibit definition of types in there parameter list of a
function declaration.
I'm not a C++ lawyer (nor even a C++ fluent speaker (although I
have "C++ Readability," go figure)), but "no type declarations in
function declarations" seems awfully restrictive:
int main(int argc, char **argv) // BZZZZT!
|
I said "type definition", not type declaration. Neither int nor char**
were defined in that declaration, they were only specified as the types
of the corresponding parameters. They aren't identifiers, they don't
have a scope associated with them. Types that have scoped identifiers
that can be defined by user code include struct, union, and enum types.
| Quote: | Useful alternative: give types defined in a function's parameter list
the same scope as the function's declaration, rather than function
prototype scope.
I'd worked up a nice reductio ad absurdum, and then realized that
you meant something other than what you'd said: You said "same scope
as the function's *declaration*," but you meant "same scope as the
function's *identifier*." I dunno: Might be reasonable, might have
unwelcome consequences in corner cases, might disable some corner
cases that are legitimate now but Ought To Be Banned (Just Think Of
The Children!), ... Needs more thought than my graying gray cells
can muster.
|
Yes, think on it. Function declarations that would be affected by this
suggestion are useless, so I don't see how it could break existing
working code. Other kinds of unwelcome consequences are certainly
possible, of course.
--
James Kuyper |
|
| Back to top |
|
 |
Alan Curry Guest
|
Posted: Sun Jun 24, 2012 12:56 am Post subject: Re: C scope and struct definitions |
|
|
In article <js5l0m$64l$1@dont-email.me>,
Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
| Quote: | On 6/23/2012 6:06 PM, Alan Curry wrote:
In article <js32rk$siv$1@dont-email.me>,
Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
On 6/22/2012 6:40 PM, Alan Curry wrote:
But is the compiler right for a real reason, or is it just a continuation of
a historical accident? Why would you ever want this behavior?
The Rationale sheds no light my tired old eyes can see. You
are welcome to read it for yourself. (Also, if you think the
normative text of the formal definition of the C language does not
qualify as "a real reason," well ...)
The standard was supposed to codify existing practice. A real reason would
have to come from before standardization. Was there a real reason for the
existence of such a small, useless scope?
Note that existing practice had no notion of prototypes at all,
so the issue of "prototype scope" simply didn't exist. (The ANSI
Standard invented other things new to the language, too: `void',
for example.)
But once you've decided to declare a function with a prototype,
what scope should any identifiers in the prototype have? It seems
pretty clear you don't want them leaking outside, else
void foo(char *p);
void bar(double *p);
... wouldn't compile, because of the conflicting declarations of `p'.
I suggest that would have been untenable.
|
Those names should simply be omitted, and it would be a good thing if they
weren't allowed either. They serve no purpose and cause problems in header
files when one header defines a macro that another header uses as an argument
name in a prototype.
We are allowed to use the intelligent comment markers /* */ in C, not just
the dumb // to-end-of-line kind, so you can say
void f(char * /*p*/, double * /*q*/);
if the parameter names are meant to be documentation.
Anyway, putting type names and variable names into a single category and
calling them "identifiers" is a false generalization. It works at the
technical level for the compiler implementor I guess, but besides that what's
the reason for lumping them together and insisting that they behave the same?
If you can't explain it without the word "identifier" then there is no
reason, it's just a thought process that's being misled by a bit of escaped
compiler-writer's jargon.
| Quote: |
I don't think we'd be losing anything if those declarations were simply
illegal. Declare your structs before your functions. They aren't variables.
I'm glad the Standard didn't take your view. While I'll admit
that function-specific types are not all that common, I'll maintain
that they are extremely useful. Most often, there's an ad-hoc
table of some kind to assist a function in the performance of its
work: Maybe an association of states with their capitols, or ranges
of `x' where a rational function/Chebyshev approximation/continued
fraction is the preferred computation method. Whatever it is, if
it's specific to the operation of one function I see *no* reason to
inflict it on others.
|
The same could be said for a function that's only called by one other
function. Should we have nested functions then?
| Quote: |
A struct describes the procedure for interpreting bits in memory. As a
procedure description, it's more like a function than a variable. It doesn't
occupy memory itself, so it doesn't have a lifetime that can end when the
function call ends. Putting it inside the function gives you nothing.
All the same statements could be made about an identifier of any
kind whatsoever. Should `x' leak out of one function into others?
|
Variable scopes make sense because the object named by the variable doesn't
exist until the function is called. A type isn't an object.
| Quote: | Variables, functions, and constant data are all defined with reference to
types. Types are the most fundamental entities in a program. They deserve
globally unique names.
I'm with you, up to the antepenultimate word. Why should a
type declared in the bowels of some function in some library I don't
even have source to be "global?" How shall I select my identifiers
to ensure that no third party's library bollixes them?
If you want "global," go back to BASICs. (By which I mean
Kemeny and Kurtz, not MS.)
|
You don't have to take "global" that far. Third party libraries occupy
separate globes. Uniqueness within a source file is a reasonable requirement.
Uniqueness within a set of files that are compiled at the same time would be
a good bonus check.
--
Alan Curry |
|
| Back to top |
|
 |
Keith Thompson Guest
|
Posted: Sun Jun 24, 2012 1:07 am Post subject: Re: C scope and struct definitions |
|
|
Eric Sosman <esosman@ieee-dot-org.invalid> writes:
| Quote: | On 6/23/2012 8:57 PM, James Kuyper wrote:
[...]
Two:
C++ way: prohibit definition of types in there parameter list of a
function declaration.
I'm not a C++ lawyer (nor even a C++ fluent speaker (although I
have "C++ Readability," go figure)), but "no type declarations in
function declarations" seems awfully restrictive:
int main(int argc, char **argv) // BZZZZT!
What must one do instead?
typedef char **charStarStar;
int main(int argc, charStarStar argv)
? But, as I say, I don't speak That Other Language, and maybe I've
read more into your synopsis than was actually present.
|
I think the restriction in C++ is that you can't define a new type name
(either a typedef name or a tag) in a prototype or as a return type.
"char**" is, in some sense, an existing type, not a new one.
I haven't found the rule in the C++ standard that states this
explicitly, but the annex that describes incompatibilities between C and
C++ mentions it.
For example, this:
void f( struct S { int a; } arg ) {}
is valid in C, but invalid in C++. (I'd say it's poor style in C.)
[...]
--
Keith Thompson (The_Other_Keith) kst-u (AT) mib (DOT) org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister" |
|
| Back to top |
|
 |
Powered by phpBB © 2001, 2006 phpBB Group
|