static const POD object

MSVC allows static const objects.
In MSVC this code:

struct A {
  int v;
};
static const a;

will compiles and a.v will be zero. But clang and gcc issue errors:
error: default initialization of an object of const type 'const struct A'
requires a user-provided default constructor
error: uninitialized const ‘a’ [-fpermissive]

There was resolved issue here:
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#78 , now
standard states:

[2003: 8.5/6]: Every object of static storage duration shall be
zero-initialized at program startup before any other initialization takes
place.

[2003: 8.5/9]: If no initializer is specified for an object, and the object
is of (possibly cv-qualified) non-POD class type (or array thereof), the
object shall be default-initialized; if the object is of const-qualified
type, the underlying class type shall have a user-declared default
constructor. Otherwise, if no initializer is specified for a nonstatic
object, the object and its subobjects, if any, have an indeterminate initial
value; if the object or any of its subobjects are of const-qualified type,
the program is ill-formed.

Looks like Judy Ward suggestion was misunderstood.

It's perfectly fine to instantiate a const static object according to this
paragraphs. And this object should be zero-initialized constant object.

MSVC allows static const objects.
In MSVC this code:

struct A {
        int v;
};
static const a;

will compiles and a.v will be zero. But clang and gcc issue errors:
error: default initialization of an object of const type 'const struct A'
requires a user-provided default constructor
error: uninitialized const ‘a’ [-fpermissive]

There was resolved issue here:
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#78 , now
standard states:

[2003: 8.5/6]: Every object of static storage duration shall be
zero-initialized at program startup before any other initialization takes
place.

[2003: 8.5/9]: If no initializer is specified for an object, and the object
is of (possibly cv-qualified) non-POD class type (or array thereof), the
object shall be default-initialized; if the object is of const-qualified
type, the underlying class type shall have a user-declared default
constructor. Otherwise, if no initializer is specified for a nonstatic
object, the object and its subobjects, if any, have an indeterminate initial
value; if the object or any of its subobjects are of const-qualified type,
the program is ill-formed.

Looks like Judy Ward suggestion was misunderstood.

It's perfectly fine to instantiate a const static object according to this
paragraphs. And this object should be zero-initialized constant object.

I don't think so.

[...] if the object is of const-qualified
type, the underlying class type shall have a user-declared default
constructor. [...]

This requires a user-declared default constructor in this case.

Dmitri

[...] if the object is of const-qualified
type, the underlying class type shall have a user-declared default
constructor. [...]

This requires a user-declared default constructor in this case.

Judy Ward suggestion was "It should be made clear that this paragraph does
not apply to static objects."

His suggestion was to allow instantiate a zero initialized static const
object. It was marked as resolved by adding "Otherwise, if no initializer is
specified for a non-static object..." So the authors of the standard either
did not understand his idea or I am right and clang shouldn't issue an error
on this code.

Now I see -- current text does not reflect his intention. He might
have intended to change the whole paragraph, but he only changed the
second sentence.

Dmitri

Actually, her proposal does not appear to have survived in C++11:

C++11 [dcl.init]p6:
  To default-initialize an object of type T means:
    • if T is a (possibly cv-qualified) class type (Clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
    • if T is an array type, each element is default-initialized;
    • otherwise, no initialization is performed.
  If a program calls for the default initialization of an object of a const-qualified type T, T shall be a class type with a user-provided default constructor.

Anyway, "static" doesn't mean what you think it means in this context; it would more naturally be interpreted as "object with static storage duration".

We can weaken this restriction in MS compatibility mode, but I don't otherwise think this is a compiler defect.

John.

We can weaken this restriction in MS compatibility mode, but I don't

otherwise think this is a compiler defect.

It should be weaken in MS compatibility mode for sure. Now clang can't
compile our sources which pass compilation on MSVC and gcc (with
-fpermissive switch). For now I have no other option...

And it is not a compiler defect. But why not to weaken this restriction by
default? What harm can it cause? Clang is not a standard compliance tester.
Allowing to instantiate static const objects will not lead to any undefined
behavior. So its pretty safe by themselves and will save nervous to someone.

This is a proposal/suggestion to provide a language extension. Here's the
documentation/process the Clang community uses to assess such proposals:

http://clang-developers.42468.n3.nabble.com/Criteria-for-Accepting-Language-Extensions-into-Clang-td3189224.html

This is a proposal/suggestion to provide a language extension. Here's the

documentation/process the Clang community uses to assess such proposals.

Ok. This suggestion is perfectly fall into category "improving compatibility
with existing compilers". It shouldn't be a problem in arguing for this
extension. MSVC and GCC can compile this code. Also it is not an extension
to the language syntax it is lowering the semantic restrictions.

And it is not a compiler defect.

It is a defect or an extension, depending on whether it was intentional or not.

But why not to weaken this restriction by
default? What harm can it cause? Clang is not a standard compliance tester.

Clang is a standards-conforming compiler. Throwing in extensions
randomly is a disservice for users, because it allows them to write
code that is not conforming, and thus non-portable between compilers.
Your codebase is actually suffering from such behavior in MSVC now --
the codebase has code that compiles and works, despite not being valid
C++.

Dmitri

It's bad code. Yes, I understand that you're porting a presumably working
code base, so you see every diagnostic as pointless interference from the
compiler. In practice, this pattern is very likely to be an error of omission:
either the initializer is missing (possible but not all that likely) or the variable
ought to be extern (so that it'll link against an initialized variable definition
in a different translation unit).

In the rare case where you really do want a global zero constant, it is quite
easy to suppress the diagnostic with an explicit initializer, e.g.:
  const foo x = foo();

John.

It's bad code. Yes, I understand that you're porting a presumably working
code base, so you see every diagnostic as pointless interference from the
compiler.

Yes now we are only start using clang. It is my initiative to set up clang
build and use it for testing with ubsan and asan, that's how I found this.

How to propose this syntax weakening to "-fms-extensions"? Just fill a new
enhancement request in bug tracker?

Better yet, submit a patch to cfe-commits.

Dmitri