I am reading again "C++ Primer, 5th edition". In chapter 16 about templates, there is an example of "template Non-type parameters":
template<unsigned N, unsigned M>
int compare(const char (&p1)[N], const char (&p2)[M])
{
return strcmp(p1, p2);
}
int main()
{
cout << compare("hi", "mom") << endl;
cout << strcmp("hi", "mom") << endl;
std::cout << "\ndone!\n";
}
As we know,
strcmp()
compares two character strings and returns0
for equality, a positive value ifstr1
is greater thanstr2
, and a negative value ifstr1
is less thanstr2
, and this is what I get insidemain()
callingstrcmp()
.The problem is in the book example that calls
strcmp()
inside the template function, so when I run the program I get:
output:
-5
-1
What is the problem in the code? And why are the two giving different values for the same arguments?
This is a compiler optimization applied when
strcmp
is passed literal parameters, even on -O0. See this compiler explorer link: https://godbolt.org/z/T4EKxrThe generated assembly:
As we can see, for
b()
above, gcc is optimizing the call tostrcmp
to just a-1
, whereas it actually callsstrcmp
fora()
. This is valid behavior, asstrcmp
returns:-1
is negative.If we turn on optimizations, gcc will similarly optimize
a()
.