4

According to Compiler Explorer, only some will build this code:

struct s { static int i; };

int main( int argc, char *argv[] )
{
  s::i = 1;
  return 0;
}

Most newer C++ compilers fail at linking.

  • GCC 4.7.2 works, 4.7.3 and newer fail
  • Clang 3.2 works, 3.4 and newer fail
  • msvc works with all versions

So, is this undefined behaviour or should this work?

dee
  • 41
  • 1
  • 1
    Does this answer your question? [static variable link error](https://stackoverflow.com/questions/9282354/static-variable-link-error) Basically the same problem. – Lukas-T Sep 07 '20 at 20:32
  • 2
    Note that undefined behaviour is unrelated to compilation or linking but occurrs at runtime. Also accessing static member without an object is not UB ... that's why `static` exists in the first place. – Lukas-T Sep 07 '20 at 20:33
  • 1
    @churill - UB has very much to do with both compilation and linking. The standard describes the behavior of the implementation, that includes translation too. If a program violates the ODR, it's UB. The manifestation can be a linker error or even appearing to "work" because something was optimized away anyway. – StoryTeller - Unslander Monica Sep 07 '20 at 20:46
  • @StoryTeller-UnslanderMonica That seems logical, though I never viewed it this way. Thanks, for clarifaing. – Lukas-T Sep 08 '20 at 05:12
  • I didn't see this as a declaration and not a definition for s::i - thanks for that. But something must have changed in the language since old compiler suits seem to happily build this code. Has there been a language clarification? (That's why i thought of UB here) – dee Sep 09 '20 at 19:44

2 Answers2

4

This code violates the One Definition Rule (ODR), which requires a single definition of every entity that is used in the program.

There is no definition of s::i in the program, but you are using it, and so the code violates the ODR. Any violation of the ODR makes the code ill-formed, no diagnostic required. This means the compiler can do anything it wants, including rejecting the code, or compiling it and producing an executable program (which could do anything it wants).

cigien
  • 57,834
  • 11
  • 73
  • 112
4

should this work?

It is not guaranteed to work.

So, is this undefined behaviour

Technically, the program is ill-formed (no diagnostic required). The distinction is largely irrelevant to the programmer, and it is safe to assume that it means same as undefined behaviour.

This is same for non-member variables as well. An equivalent non-member example is:

extern int global_variable;
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
eerorika
  • 232,697
  • 12
  • 197
  • 326