2

Anyone knows why the following code works under g++ 4.7.2? If I change the name printf to another name such as f, it has compiler error saying constexpr can't contain non-const function calls (which I think is the correct behavior).

[hidden]$ cat d.cpp 
extern "C" { extern int printf(const char* s, ...); }
constexpr int g() { return printf(""), 0; }
template <int N> struct X { const static int value = N; };
int n = X<g()>::value;
[hidden]$ g++ -std=c++11 -c d.cpp
[hidden]$ g++ -v |& tail -1
gcc version 4.7.2 20121109 (Red Hat 4.7.2-8) (GCC) 

Note I don't include any header files.

Kan Li
  • 8,557
  • 8
  • 53
  • 93

2 Answers2

4

printf() is handled as a builtin function by GCC/g++ in many cases (though I think this behavior is still a bug). From http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html:

The ISO C90 functions ... printf ... are all recognized as built-in functions unless -fno-builtin is specified (or -fno-builtin-function is specified for an individual function)

You get the correct diagnostic if you use the -fno-builtin option.

The bug appears to be fixed in 4.8.0.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • Good to hear it is fixed in 4.8.0 – Kan Li May 17 '13 at 21:25
  • `gcc 4.8.2` still allows `printf` and other [builtins in a constexpr](http://stackoverflow.com/questions/22176777/why-can-i-call-a-non-constexpr-function-inside-a-constexpr-function). My gut says this is not strictly conformant unless they document this as an extension. – Shafik Yaghmour Mar 04 '14 at 18:37
-1

I think stdio.h is included by default

I try it with puts and works for me [gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1)]

extern "C" { extern int puts(const char* s); }
constexpr int g() { return puts(""), 0; }
template <int N> struct X { const static int value = N; };
int n = X<g()>::value;

Edit:

@Keith Thompson

Before I wrote "included by default" I tried the code below without #include <stdio.h>. It compiles with some warnings but runs - so (for some reason) printf, scanf, puts works without #include <stdio.h>. Maybe stdio.h is not included by default, maybe library with printf, scanf, puts is linked by default.

int main()
{
    char one;

    printf("Hello ");
    scanf("%c", &one);
    puts("world!");
}
furas
  • 134,197
  • 12
  • 106
  • 148
  • 2
    I don't believe *any* header is included by default. Try declaring `FILE *foo` without `#include `; you'll find that the identifier `FILE` is not visible. – Keith Thompson May 17 '13 at 22:15