Topic: scope of argument lists in function declarations?
Author: larsn@Autodesk.COM (Lars Nyman)
Date: 22 Jun 92 17:11:44 GMT Raw View
> Thanks for pointing me to the right place in the ARM! The only
> problem I have with this difference from ANSI C is that it would be
> easier to declare "struct mumble" in the lexically enclosing class
> scope than at file scope if it was first declared in the return or
> argument type of a member function. That's an implementation problem,
> however, and users who are too lazy to declare the class before using
> it wouldn't appreciate C++ thinking they were referring to nested
> classes (the rare case) instead of global classes (the common case).
ARM p15:
"A name first declared by a friend declaration belongs to the global
scope; the same is true for the name of a class first declared in a
return or argument type".
ARM p250:
"If a class or a function mentioned as a friend has not been declared
its name is entered in the same scope as the name of the class containing
the friend declaration".
??? So what scope should it be entered in ???
Also, ARM p139:
"Types may not be defined in return or argument types".
However, types may be *declared* in return and argument types. And according
to ARM p15 the type name is entered in file scope.
Author: jimad@microsoft.com (Jim Adcock)
Date: 22 Jun 92 17:29:02 GMT Raw View
In article <1992Jun20.151946.7507@lpi.liant.com> pkt@lpi.liant.com (Scott Turner) writes:
|had been resolved within AT&T at the time the ARM was written, but
....
|change from ANSI C. The C++ standards committee is comfortable with
|this difference.
Has this AT&T change from ANSI-C been voted into the working draft, and if
so what line and page?
Author: interran@uluru.Stanford.EDU (John Interrante)
Date: 17 Jun 92 17:30:37 Raw View
Someone recently said in either comp.lang.c++ or comp.std.c++ that
function declarations like void foo(class Ccxn*) will have the effect
of declaring class Ccxn at file scope. I can't find where it says in
the ARM this should be done, though, and according to GNU CC's texinfo
documentation the ANSI C standard doesn't allow that behavior either:
* Users often think it is a bug when GNU CC reports an error for code
like this:
int foo (struct mumble *);
struct mumble { ... };
int foo (struct mumble *x)
{ ... }
This code really is erroneous, because the scope of `struct
mumble' the prototype is limited to the argument list containing
it. It does not refer to the `struct mumble' defined with file
scope immediately below--they are two unrelated types with similar
names in different scopes.
But in the definition of `foo', the file-scope type is used
because that is available to be inherited. Thus, the definition
and the prototype do not match, and you get an error.
This behavior may seem silly, but it's what the ANSI standard
specifies. It is easy enough for you to make your code work by
moving the definition of `struct mumble' above the prototype.
It's not worth being incompatible with ANSI C just to avoid an
error for the example shown above.
So why do both cfront 3.0.1 and g++ 2.2.2 compile the following code
silently, even though gcc 2.2.2 emits the advertised error messages?
extern void foo(struct mumble* x);
struct mumble {
int nbr_;
};
void foo(struct mumble* x) {
x->nbr_ = 9;
}
t.c:1: warning: `struct mumble' declared inside parameter list
t.c:1: warning: its scope is only this definition or declaration,
t.c:1: warning: which is probably not what you want.
t.c:7: conflicting types for `foo'
t.c:1: previous declaration of `foo'
--
John Interrante / interran@uluru.stanford.edu
Computer Systems Laboratory, Stanford University
Author: interran@uluru.Stanford.EDU (John Interrante)
Date: 17 Jun 92 23:48:43 Raw View
Ah, somebody reminded me that it's legal in C++ to overload two
different functions. So both cfront and g++ could have thought these
two functions were different and still compiled the code without any
error messages. I modified the test to make certain that neither
cfront nor g++ would be able to compile it unless they really, honest
to goodness, did declare `struct mumble' at file scope despite it
appearing in a parameter list. Here's the new test:
extern "C" void foo(struct mumble* x);
mumble* global_x = 0;
struct mumble {
int nbr_;
};
void foo(mumble* x) {
x->nbr_ = 9;
}
Both cfront 3.0.1 and g++ 2.2.2 compiled this code as well without any
error messages, which means that the declaration of `struct mumble' in
foo's prototype does indeed refer to the `struct mumble' defined with
file scope immediately below. If struct mumble's scope had been
restricted to the parameter list containing it, I would not have been
able to declare a variable at file scope using `mumble' as a typedef
name (`mumble' would not have been in scope yet) or define the extern
"C" function foo (the `mumble' in foo's definition would have been
unrelated to the `mumble' in foo's declaration).
It appears I've stumbled into an area where neither cfront nor g++
conform to the ARM (yes, I finally found something in the ARM to
specify what should happen in such a case). The third line of page
139 says that types may not be defined in functions' return or
argument types. The ANSI C standard (if the GNU CC documentation is
correct) supposedly requires compilers to issue diagnostics in this
case.
--
John Interrante / interran@uluru.stanford.edu
Computer Systems Laboratory, Stanford University
Author: sjm@bcrki65.bnr.ca (Stuart MacMartin)
Date: Thu, 18 Jun 1992 13:38:48 GMT Raw View
I seem to have missed the first part of this discussion.
I thought I understood things. Now things have been explained to the point
where I no longer know what is going on.
So I am now going to ask a totally stupid question. One that should never
appear in a discussion group like this because it is too basic.
When does "const" mean "this thing will not change"?
And when does it mean "this thing isn't really supposed to be changed,
but it might anyway"?
Put another way: When does "const" mean "const"?
I apologize for asking a question that should never appear here, but...
you guys asked for it.
Stuart
: Stuart MacMartin email: sjm@bnr.ca :
: Bell-Northern Research phone: (613) 763-5625 :
: PO Box 3511, Stn C, Ottawa, K1Y-4H7, CANADA Standard disclaimers apply. :
Author: pkt@lpi.liant.com (Scott Turner)
Date: Sat, 20 Jun 1992 15:19:46 GMT Raw View
> The third line of page
> 139 says that types may not be defined in functions' return or
> argument types. The ANSI C standard (if the GNU CC documentation is
> correct) supposedly requires compilers to issue diagnostics in this
> case.
The issue of the meaning of
extern "C" void foo(struct mumble* x);
had been resolved within AT&T at the time the ARM was written, but
may not have been mentioned explicitly. C++ is different from ANSI C,
in that the above declaration declares "struct mumble" at file scope.
The best support for this that I can find in the ARM is section 3.2
(Scopes) which lists the kinds of scope: local, function, file, and
class. Note that there is no "prototype" scope. This was a deliberate
change from ANSI C. The C++ standards committee is comfortable with
this difference.
Both cfront 3.0.1 and g++ 2.2.2 are correct.
--
Prescott K. Turner, Jr.
Liant Software Corp. (developers of LPI language products)
959 Concord St., Framingham, MA 01701 USA (508) 872-8700
UUCP: ...uunet!lpi!pkt Internet: pkt@lpi.liant.com
Author: interran@uluru.Stanford.EDU (John Interrante)
Date: 20 Jun 92 16:16:28 Raw View
> The issue of the meaning of
> extern "C" void foo(struct mumble* x);
> had been resolved within AT&T at the time the ARM was written, but
> may not have been mentioned explicitly. C++ is different from ANSI C,
> in that the above declaration declares "struct mumble" at file scope.
> The best support for this that I can find in the ARM is section 3.2
> (Scopes) which lists the kinds of scope: local, function, file, and
> class. Note that there is no "prototype" scope.
You're right. In fact, section 3.2 even explicitly mentions this case
(I just never noticed it before). On page 15, the last sentence of
the class scope paragraph says:
A name first declared by a friend declaration (%11.4) belongs to
the [file] scope; the same is true for the name of a class first
declared in a return or argument type.
Thanks for pointing me to the right place in the ARM! The only
problem I have with this difference from ANSI C is that it would be
easier to declare "struct mumble" in the lexically enclosing class
scope than at file scope if it was first declared in the return or
argument type of a member function. That's an implementation problem,
however, and users who are too lazy to declare the class before using
it wouldn't appreciate C++ thinking they were referring to nested
classes (the rare case) instead of global classes (the common case).
--
John Interrante / interran@uluru.stanford.edu
Computer Systems Laboratory, Stanford University