12

What does the following construction mean?

#include <iostream>

template <int ...> struct s;

int main() {
    int i = s<,>::xxx;

    std::cout << i << std::endl;
}

It is compiled by gcc 4.4.5+ and when executed outputs 0.

Martin B
  • 23,670
  • 6
  • 53
  • 72
Igor Milyakov
  • 602
  • 5
  • 7
  • It outputs some random value on my machine. The initialization of `i` is somehow ignored and the unitialized value of `i` is printed. – jrok May 30 '12 at 10:59
  • 5
    It doesn't look legal. `s` is never defined (and does not contain an `xxx` member) and templates must be given non-empty parameters. (I compiled it with gcc 4.6.2, and it printed `32767`, clang won't compile it). – Mankarse May 30 '12 at 10:59
  • Changing the names of `s` or `xxx` does not change the behaviour. This is almost certainly a bug in gcc. It seems the bug is triggered by supplying empty arguments to a variadic template. – Mankarse May 30 '12 at 11:10
  • Interestingly, the problem still occurs even if `s` is defined and contains a member called `xxx`. Code just doesn't get generated for any expression containing `s<,>::xxx`. – Mankarse May 30 '12 at 11:20
  • It won't compile for me. I get the error: syntax error: missing ',' before '...' 'xxx': is not a member of ''global namespace'' – Rhexis May 30 '12 at 11:56
  • @Mankarse: clang 3.0 complains with *error: expected expression* and points to the comma, do you have a more recent version with a better diagnosis ? – Matthieu M. May 30 '12 at 12:12
  • @Flyphe: Which compiler? If gcc, do you pass the `-std=c++0x`-switch? – Magnus Hoff May 30 '12 at 12:12
  • mmmm im using visual studio 2010 however I tried it in cygwin and it complied fine. Interesting. – Rhexis May 30 '12 at 12:24
  • @MatthieuM.: I'm using trunk, and the diagnostic is the same. It seems like a valid diagnosis though. – Mankarse May 30 '12 at 12:57
  • @Mankarse: definitely looks valid, I just wondered if it was more explicit :) – Matthieu M. May 30 '12 at 13:02
  • @MatthieuM. To me that sounds like the best possible diagnostic. It's pretty much what I thought when I looked at it: "hey, you need to put a thing there!" What else can one say about it? – R. Martinho Fernandes May 30 '12 at 14:07
  • @R.MartinhoFernandes: It's not bad per se, but I am used to more verbose diagnostics from clang :) – Matthieu M. May 30 '12 at 14:18
  • 1
    Reported as a gcc bug, http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53531 – Jonathan Wakely May 30 '12 at 16:23
  • 1
    Even more interesting the situation with string: { string i = s<,>::xxx; std::cout << i << std::endl; } The object is allocated, but not constructed. – Igor Milyakov May 31 '12 at 06:30

1 Answers1

13

I rewrote the program to this:

template <int ...> struct s;

int main() {
    int i = s<,>::xxx;

    return i;
}

and compiled it with the -S-switch, to get assembly output that I cleaned up to the following:

main:
        pushq   %rbp
        movq    %rsp, %rbp
        movl    -4(%rbp), %eax
        popq    %rbp
        ret

Now, my asm is a bit rusty, but the only significant code seems to be movl -4(%rbp), %eax, which sets the return value to whatever it can read from i. In other words, the program simply returns whatever was on top of the stack when the main function was entered. This seems to corroborate @jrok's comment that the initialization of i is somehow ignored. No code has been generated for the mystical s<,>::xxx-expression.

Bottom line; this looks like a compiler bug. The compiler should have given an error message.

Corroborating side note: I get identical assembly output for the program int main() { int i; return i; }.

Magnus Hoff
  • 21,529
  • 9
  • 63
  • 82