imagine have this:
void f(struct s *);
from reading standard ($6.2.1) i'm kinda confused @ scope of tags. first there this:
a label name kind of identifier has function scope. can used (in goto statement) anywhere in function in appears, , declared implicitly syntactic appearance (followed : , statement).
every other identifier has scope determined placement of declaration (in declarator or type specifier). if declarator or type specifier declares identifier appears outside of block or list of parameters, identifier has file scope, terminates @ end of translation unit. if declarator or type specifier declares identifier appears inside block or within list of parameter declarations in function definition, identifier has block scope, terminates @ end of associated block. if declarator or type specifier declares identifier appears within list of parameter declarations in function prototype (not part of function definition), identifier has function prototype scope, terminates @ end of function declarator. if identifier designates 2 different entities in same name space, scopes might overlap. if so, scope of 1 entity (the inner scope) end strictly before scope of other entity (the outer scope). within inner scope, identifier designates entity declared in inner scope; entity declared in outer scope hidden (and not visible) within inner scope.
as identifier properties being defined as:
- an identifier can denote object; function; a tag or member of structure, union, or enumeration; typedef name; label name; macro name; or macro parameter. same identifier can denote different entities @ different points in program. member of enumeration called enumeration constant. macro names , macro parameters not considered further here, because prior semantic phase of program translation occurrences of macro names in source file replaced preprocessing token sequences constitute macro definitions.
which leads me conclusion:
as type specifier struct s
declares identifier s
within "the list of parameter declarations in function prototype" has (the identifier s
) function prototype scope. means this:
void f2() { //inside **some** function block after above declaration struct s { int a; } v; //new s identifier being declared f(&v); //not compatible types }
but after have:
- structure, union, , enumeration tags have scope begins after appearance of tag in type specifier declares tag. each enumeration constant has scope begins after appearance of defining enumerator in enumerator list. other identifier has scope begins after completion of declarator.
which means entirely different:
void f3() { //inside **some** function block after above declaration struct s { int a; } v; //completing incomplete type f(&v); //ok }
seems gcc , clang follows p4 (summered warning of compiling declaration of f
):
warning: ‘struct s’ declared inside parameter list not visible outside of definition or declaration void f(struct s *);
similar case using clang:
warning: declaration of 'struct s' not visible outside of function [-wvisibility] void f(struct s *);
anyone care explain right way determine scope of s
identifier in function prototype f
?
i'm referring incits/iso/iec 9899-2011[2012] standard paper; compiling gcc compiler (and clang) following flags:
-std=c11 -pedantic
request complete piece of code:
currently (by compiling gcc , clang) this:
void f(struct s {int _;}); struct s g;
will give following error (by clang):
prog.c:1:15: warning: declaration of 'struct s' not visible outside of function [-wvisibility] void f(struct s {int _;}); ^ prog.c:3:10: error: tentative definition has type 'struct s' never completed struct s g; ^ prog.c:3:8: note: forward declaration of 'struct s' struct s g;
which quoting standard may or may not right behavior in case (conflicting p4 , p7 - or they? - don't know).
by p7 struct s
in declaration of g
should refer same identifier declared in function prototype of f
. , there shouldn't compiler errors caused defining variable incomplete type.
but p4 struct s
declared in function prototype of f
must have scope terminates @ end of function declarator. , declaration of struct s
in declaration of g
should create identifier s
(being tag of incomplete structure , error messages).
first , foremost, not allowed define class within parameter list. cannot find compiler compile void f(struct s {int _;});
, perhaps had non-conforming 1 when asked question. can find rule in standard @ [dcl.fct]:
types shall not defined in return or parameter types.
second, according c++03 (iso/iec 14882:2003) standard way through c++17 (n4659), rules regarding forward declaration of type within parameter list have not changed ([basic.scope.pdecl]):
if elaborated-type-specifier used in decl-specifier-seq or parameter-declaration-clause of function defined in namespace scope, identifier declared class-name in namespace contains declaration
therefore scope of type forward declare within function's parameter list in namespace of function. still must define type before use it. code following legal since c++03: demo
void f(struct s); // forward declares s struct s{int i;}; // defines s forward declared above void f(s a){ // use s std::cout << a.i << std::endl; } int main() { s g; g.i = 0; f(g); }
to more answer question, struct s
forward declare within function f
has namespace scope.
Comments
Post a Comment