https://bugs.llvm.org/show_bug.cgi?id=40347

            Bug ID: 40347
           Summary: designated initializers (c99 feature) accepted when
                    c++11 standard requested
           Product: clang
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: C++11
          Assignee: unassignedclangb...@nondot.org
          Reporter: andi.m.mccl...@gmail.com
                CC: blitzrak...@gmail.com, dgre...@apple.com,
                    erik.pilking...@gmail.com, llvm-bugs@lists.llvm.org,
                    richard-l...@metafoo.co.uk

Created attachment 21344
  --> https://bugs.llvm.org/attachment.cgi?id=21344&action=edit
BUILD SCRIPT FOR MAIN.CPP

REPRO STEPS

Here's a simple program.

//////////

#include "stdio.h"

#define LEFT 0
#define RIGHT 1

const char *test[] = {
    [LEFT] = "left",
    [RIGHT] = "right",
};

int main() {
        printf("%s\n", test[LEFT]);
        return 0;
}

//////////

I save this as main.cpp. I build this using the attached CMakeLists.txt, which
happens to produce the invocation line:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
   -std=c++11 -o CMakeFiles/clangtest.dir/main.cpp.o -c
/Users/mcc/work/h/clangbug/main.cpp

EXPECTED BEHAVIOR

This program should not compile. The [LEFT]= [RIGHT]= stuff is an example of
the "designated initializer" feature. This is a feature of C99, but I
understand it is not a feature of C++11. I do not find it in the N3242 draft
(section 8.5, "Initializers") and several people I trust assure me that it is
not a C++11 feature.

The fact I requested -std=c++11 implies that the C++11 standard is what I
wanted, not some significantly amended standard.

OBSERVED BEHAVIOR

The program works and prints "left".

If I add to the command line -Werror=c99-extensions, or add to the CMakeLists
set (CMAKE_CXX_FLAGS -Werror=c99-extensions), it fails with the helpful error
message "designated initializers are a C99 feature".

COMMENTS / "WHY I CARE"

The context of this bug report is that I have a program which must work cross
platform. In particular it must compile in standard OS X Clang, in standard
Android Native Development Kit Clang, and in standard Microsoft Visual Studio.
I do not always have access to my Visual Studio workstation, and so it is a
great imposition if when I sit down at my Visual Studio workstation I discover
only then that the program does not compile. The best way I know to ensure that
it will compile in Visual Studio is to target the standard, which Microsoft is
much better now at following than they used to be. I try to get my compilers to
target the standard by placing this in my CMakeLists.txt: 

set (CMAKE_CXX_STANDARD 11)
set (CMAKE_CXX_EXTENSIONS OFF)

The way CMake interprets my request for EXTENSIONS OFF when targeting clang is
to insert -std=c++11 when invoking clang. If EXTENSIONS is ON or is not set, it
passes -std=gnu++11 . In other words, at least one major open source project
jumped to the same conclusion I did in my "EXPECTED BEHAVIOR", that std=c++11
means the unadorned standard and this is in fact the reasoning for separating
c++11 and gnu++11.

Today I needed to do a quick test of my project on Windows. I checked out and
built. It did not work. MSVC failed (correctly) on the designated initializer
line. That had snuck in at some point and I did not know it was not valid C++.
I had to waste time at a very inconvenient moment trying to understand why it
wasn't compiling. Ironically, I think? that MSVC in other modes *will* support
C99 features in C++, but for this build I had requested the C++11 standard so
apparently that's what it applied. -std=c++11 had not succeeded at the task I
wanted it for.

THE THIRD STAGE OF GRIEF IS BARGAINING

I don't know what kinds of considerations resulted in -std=C++11 mode including
C99 extensions. Maybe this is as-intended. (I'd personally prefer Clang allow
C99 features in C++, *if* I wasn't on a project where portability is
important.) However *even if* this is as-intended, this is *still* a bug
insofar as it is a documentation bug. If I look at

https://clang.llvm.org/docs/ClangCommandLineReference.html

all it says re: -std is 
"-std=<arg>, --std=<arg>, --std <arg>
Language standard to compile for"
`man clang` on OS X says the same.

There is a separate page,
https://clang.llvm.org/cxx_status.html
which discusses C++ compliance status. It flatly says "Clang 3.3 and later
implement all of the ISO C++ 2011 standard." and gives *no* indication of a
major divergence like C99 extensions. (Given the level of detail on this page,
I would call such an omission actively misleading.)

The important thing to me is things should be predictable. I should be able to
predict what my builds will do based on the documentation.

I would expect that the -std= documentation would tell me what the options for
-std are, or how to look up what they are.

If -std=c++11 means something other than the "obvious" meaning (compliant
c++11) then the documentation should explain what that "something other" is. If
there is some specific set of flags that gets me "actually the c++11 standard",
the explanation of -std should document what those are.

The current situation is bad because
(1) I could not predict selecting c++11 would give me C++11 + C99
(2) Apparently, the CMake project could not predict this either
(3) Now that I know -std=C++11 is modified, I have no way of knowing *how
much*-- I could place -Werror=c99-extensions but I do not know if there are
other significant extensions also
(4) Since I don't truly know how to request "C++11, no extensions" I cannot go
to CMake and file a bug on *them* telling them to add -Werror=c99-extensions in
EXTENSIONS OFF mode
(5) An average user with less knowledge of standards politics than me would
probably not be able to figure out why XCode and MSVC are behaving differently
and would probably not have been able to find -Werror=c99-extensions on their
own.

CONFIGURATION

clang -v prints
Apple LLVM version 9.0.0 (clang-900.0.39.2)
Target: x86_64-apple-darwin17.3.0
It's from XCode. A Google search suggests this is equivalent to LLVM 4.0. My
test machine is running OS X 10.13.2.

I marked this bug as "trunk" because I tested with "godbolt.org" and I got the
same results as locally with both "x86-64 clang 7.0.0" and "x86-64 clang
trunk".

My cmake is
cmake version 3.10.3
I think it's from Homebrew.

For comparison, my Visual Studio is 15.0 (which I think is VS2017) on Windows
10.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to