Grammatical constituents of object type.

  • Thread starter Steven T. Hatton
  • Start date
S

Steven T. Hatton

What are the formal grammatical constituents of object type in C++? In
particular, is `extern' part of the type? The reason I ask is because the
following code won't compile without specifying the char const[] to be
extern. Looking at the Standerd suggests to me that
storage-class-specifier is /not/ part of type-specifier. The example in
§14.3.2 suggest to me that it should compile.

template<class T, char* p> class X {
// ...
X();
X(const char* q) { /* ... */ }
};

X<int,"Studebaker"> x1; // error: string literal as template-argument

char p[] = "Vivisectionist";

X<int,p> x2; // OK


I really don't care if my compiler is a bit non-compliant in this regard.
It's probably keeping me out of trouble if it is. I just feel as though I
should be able to resolve such a question by formally examining the
standard. Here's the code:

#include <iostream>

struct Virtue {
virtual std::eek:stream& print( std::eek:stream& out )const
{ return out<<"I am a struct called Virtue" <<std::endl; }
};

template <const char* T>
struct Temporal: public Virtue {
std::eek:stream& print( std::eek:stream& out )const
{ return out<<"I am a an instantiated template instance with
T="<<T<<std::endl; }
};

struct Stubborn: public Virtue {
template <const char* T>
std::eek:stream& print( std::eek:stream& out )const
{ return out<<"I am just plain "<<T<<std::endl; }
};


std::eek:stream& operator<<( std::eek:stream& out, const Virtue& v ) { return
v.print(out); }

//won't compile unless these are extern
extern char const text[]= "Temporal 1";
extern char const stub[]= "Stubborn";

int main(){

Virtue v;
Temporal <text>t;
Stubborn s;
std::cout<<v<<t<<s;

}

Here's the complaint I get if I remove extern from the first array
definition:

g++ -o contrived main.cpp
main.cpp: In function ?int main()?:
main.cpp:65: error: ?text? cannot appear in a constant-expression
main.cpp:65: error: template argument 1 is invalid
main.cpp:65: error: invalid type in declaration before ?;? token

Opinions?
 
S

Steve Pope

Steven T. Hatton said:
What are the formal grammatical constituents of object type in C++? In
particular, is `extern' part of the type? The reason I ask is because the
following code won't compile without specifying the char const[] to be
extern. Looking at the Standerd suggests to me that
storage-class-specifier is /not/ part of type-specifier. The example in
§14.3.2 suggest to me that it should compile.

template<class T, char* p> class X {
// ...
X();
X(const char* q) { /* ... */ }
};

X<int,"Studebaker"> x1; // error: string literal as template-argument

char p[] = "Vivisectionist";

X<int,p> x2; // OK


I really don't care if my compiler is a bit non-compliant in this regard.
It's probably keeping me out of trouble if it is. I just feel as though I
should be able to resolve such a question by formally examining the
standard. Here's the code:

#include <iostream>

struct Virtue {
virtual std::eek:stream& print( std::eek:stream& out )const
{ return out<<"I am a struct called Virtue" <<std::endl; }
};

template <const char* T>
struct Temporal: public Virtue {
std::eek:stream& print( std::eek:stream& out )const
{ return out<<"I am a an instantiated template instance with
T="<<T<<std::endl; }
};

struct Stubborn: public Virtue {
template <const char* T>
std::eek:stream& print( std::eek:stream& out )const
{ return out<<"I am just plain "<<T<<std::endl; }
};


std::eek:stream& operator<<( std::eek:stream& out, const Virtue& v ) { return
v.print(out); }

//won't compile unless these are extern
extern char const text[]= "Temporal 1";
extern char const stub[]= "Stubborn";

int main(){

Virtue v;
Temporal <text>t;
Stubborn s;
std::cout<<v<<t<<s;

}

Here's the complaint I get if I remove extern from the first array
definition:

g++ -o contrived main.cpp
main.cpp: In function ?int main()?:
main.cpp:65: error: ?text? cannot appear in a constant-expression
main.cpp:65: error: template argument 1 is invalid
main.cpp:65: error: invalid type in declaration before ?;? token

Opinions?

My opinion:

The combined use of "const" and a constant initializer (in this
case a string) tells the compiler to go ahead and substitute
the initializer for any instances of the variable in the file
being compiled (in the manner of #define). Once it's done this, you
run into the rule (discussed in the "local classes" thread) that
parameters of a template instantiation must have external linkage.

Steve
 
S

Steven T. Hatton

Steve Pope wrote:
My opinion:

The combined use of "const" and a constant initializer (in this
case a string) tells the compiler to go ahead and substitute
the initializer for any instances of the variable in the file
being compiled (in the manner of #define). Once it's done this, you
run into the rule (discussed in the "local classes" thread) that
parameters of a template instantiation must have external linkage.

Steve

Thank you. Removing the const qualifier also allowed the program to
compile.

http://publib.boulder.ibm.com/infoc.../com.ibm.xlcpp8a.doc/language/ref/cplr062.htm

"In C++ a global const object without an explicit storage class is
considered static by default, with internal linkage."

That seems to explain the behavior. It also explains something else I have
puzzled over for quite some time. From the Standard: "Although entities in
an unnamed namespace might have external linkage, they are effectively
qualified by a name unique to their translation unit and therefore can
never be seen from any other translation unit." I found that I had to make
my const char[] external, but that cause ODR violations unless I also put
it in an unnamed namespace. What I have yet to attempt is putting the
definition in a single implementation file, which I have read, is the
preferable method of resolving this problem.

I have to say this aspect of C++ falls in second place to Cpp as a major
source of stumbling block in my learning C++. I am finally beginning to
understand what's actually happening.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top