aCC vs g++

M

Michael Krause

Hello group,

I was wondering, is there anything in this short snippet of code that
violates some C++ standard?

-- cut here --

static void
f (double *z)
{
}


template <class T>
static void g (T *y)
{
f(y);
}

int
main (int argc, char **argv)
{
double x = 0.0;

g(&x);

return 0;
}

-- cut here --

Reason I am asking is, g++ 3.3.2 compiles fine, whereas HP's aCC
B3910B A.03.37 and B3910B A.03.31 produce this error message:

Error 328: "msng.c", line 11 # Function 'f' has not been defined yet; cannot call.
f(y);
^
Error 556: "msng.c", line 19 # Unable to generate specialization "void g<double>(double *)" due to errors during generation.
g(&x);
^^^^^
Error 556: "msng.c", line 19 # Unable to generate specialization "void g<double>(double *)" due to errors during generation.
g(&x);
^^^^^

I am a bit reluctant to say this is a compiler bug, because I've been
using templates for only two days, so maybe I'm just being stupid :)

Any help on this would be very much appreciated!

bye,
 
J

John Carson

Michael Krause said:
Hello group,

I was wondering, is there anything in this short snippet of code that
violates some C++ standard?

-- cut here --

static void
f (double *z)
{
}


template <class T>
static void g (T *y)
{
f(y);
}

int
main (int argc, char **argv)
{
double x = 0.0;

g(&x);

return 0;
}

-- cut here --

Reason I am asking is, g++ 3.3.2 compiles fine, whereas HP's aCC
B3910B A.03.37 and B3910B A.03.31 produce this error message:

Error 328: "msng.c", line 11 # Function 'f' has not been defined yet;
cannot call. f(y);
^
Error 556: "msng.c", line 19 # Unable to generate specialization
"void g<double>(double *)" due to errors during generation.
g(&x); ^^^^^
Error 556: "msng.c", line 19 # Unable to generate specialization
"void g<double>(double *)" due to errors during generation.
g(&x); ^^^^^

I am a bit reluctant to say this is a compiler bug, because I've been
using templates for only two days, so maybe I'm just being stupid :)

Any help on this would be very much appreciated!

bye,


VC++ 7.1 accepts it but Comeau rejects it. I don't know why, but if you
remove the static keyword from the definition of f, then Comeau accepts it
(along with VC++ 7.1).
 
T

tom_usenet

Hello group,

I was wondering, is there anything in this short snippet of code that
violates some C++ standard?

-- cut here --

static void
f (double *z)
{
}


template <class T>
static void g (T *y)
{
f(y);

The f called above is a dependent name, since its meaning depends on
T. This means it is looked up at the point of instantiation.
}

int
main (int argc, char **argv)
{
double x = 0.0;

g(&x);

return 0;
}

Point of instantation of g<double> is here (immediately following
main, where g<double> is used).

f is looked up here, but only external declarations are checked, so
your static f isn't found. See 14.6.4.2 of the standard for details.
I am a bit reluctant to say this is a compiler bug, because I've been
using templates for only two days, so maybe I'm just being stupid :)

This highlights why "static" in the context you have used it above is
deprecated in the C++ standard. Use anonymous namespaces instead:

namespace
{
void f(double *z)
{
}

template <class T>
void g(T *y)
{
f(y);
}
}

int main(int argc, char **argv)
{
double x = 0.0;
g(&x);
return 0;
}

Tom
 
M

Michael Krause

static void
f (double *z)
{
}


template <class T>
static void g (T *y)
{
f(y);

The f called above is a dependent name, since its meaning depends on
T. This means it is looked up at the point of instantiation.
}

int
main (int argc, char **argv)
{
double x = 0.0;

g(&x);

return 0;
}

Point of instantation of g<double> is here (immediately following
main, where g<double> is used).

f is looked up here, but only external declarations are checked, so
your static f isn't found. See 14.6.4.2 of the standard for details.
I am a bit reluctant to say this is a compiler bug, because I've been
using templates for only two days, so maybe I'm just being stupid :)

This highlights why "static" in the context you have used it above is
deprecated in the C++ standard. Use anonymous namespaces instead: [...]

Wow, it works. Just leaving out the 'static' in the definition of f
fixes my problem, too. Seems like I was thinking too much "C" here,
please excuse :)

I suppose there is a good reason why only external declarations for f
are checked during instantiation of g<double>?

Thanks again,
 
T

tom_usenet

Wow, it works. Just leaving out the 'static' in the definition of f
fixes my problem, too. Seems like I was thinking too much "C" here,
please excuse :)

I suppose there is a good reason why only external declarations for f
are checked during instantiation of g<double>?

I suspect it has something to do with avoiding violations of the ODR
in template instantiations, export, etc. Implicit template
instantiations from different translation units have to be merged (or
only one generated in the first place), and names with internal
linkage might cause some problems with this.

Certainly the rule could have been avoided, but deprecating static
works just as well, since there's no good reason to use it in C++.

Tom
 

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

Forum statistics

Threads
474,163
Messages
2,570,897
Members
47,434
Latest member
TobiasLoan

Latest Threads

Top