I ran into a problem with some C code like this:
struct SomeType { ...details immaterial... };
static struct SomeType array[] =
{
{ ... },
...
{ ... },
};
enum { ARRAY_SIZE = sizeof(array) / sizeof(array[0]) };
The Unix compilers (various versions of GCC, and the compilers on AIX and HP-UX) were all quite happy with the enum
. MSVC 2005 objected with error C2056: Illegal Expression
. According to MSDN, this is because 'An expression was invalid because of a previous error'. This was the only error reported, which makes it slightly surprising.
However, my questions are:
- Is MSVC 2005 accurately interpreting the C89 standard in disallowing the
enum
? - Are the Unix compilers being too generous in permitting this without warning?
- Does C99 (or C2011) make any difference?
- Do more recent versions of MSVC still object to the
enum
?
FWIW: the acceptable solution was to change the enum
into:
static int const ARRAY_SIZE = sizeof(array) / sizeof(array[0]);
Deprecated options are troublesome
Michael Burr gave some extra information which is very valuable, and has allowed me to unlock the problem.
Compilable example (isomorphic with the actual problems):
static const char *names[] = { "abc", "def", "ghi" };
enum { NAMES_SIZE = sizeof(names) / sizeof(names[0]) };
static const struct stuff { const char *name; int flags; } array[] =
{
{ "abc", 1 },
{ "def", 2 },
{ "ghi", 3 },
};
enum { ARRAY_SIZE = sizeof(array) / sizeof(array[0]) };
The precise version of the MSVC (as given by cl
) is:
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86
That's the version Michael says works.
And, I've found the cause of my problem. (The command lines below remove all the project-specific guff — the multitude of /D and /I options that aren't needed for the sample code.) Compiling with:
cl /W3 /c /LD /MD /Od aaa.c
And the code above compiles OK.
cl /Zg /W3 /c /LD /MD /Od aaa.c
This generates first the warning:
cl : Command line warning D9035 : option 'Zg' has been deprecated and will be removed in a future release
I've been bitching about compilations being done with deprecated options for a year or more, but no-one from the team in charge of this sub-project has been willing to stand up and fix it, and I'm not supposed to — something that's about to change.
and then it says:
aaa.c(2) : error C2056: illegal expression
aaa.c(10) : error C2056: illegal expression
So, not only is the /Zg
option deprecated but it is also the cause of the trouble in the first place. Now I've got some better ammunition to go after people with!
Thanks for the extra information, Michael.
PS: The MSDN page about /Zg
says:
If you use the
/Zg
option and your program contains formal parameters that havestruct
,enum
, orunion
type (or pointers to such types), the declaration of eachstruct
,enum
, orunion
type must have a tag (name).
That isn't wholly accurate. There are no formal parameters in the example fragment, and the enum
values were never passed to a function. But without the tag on the enum
, the error still appears with the /Zg
flag.
(No; I'm not particularly attached to MSVC 2005. The group I work in simply hasn't upgraded to anything more recent yet. Mostly it doesn't affect me. There are occasions, like this, when it hurts a lot. One day, I'll work out why the other builds on Windows seem to be accepting the enum
; I fear that I'll find this particular sub-product is out of line with everything else and using an older compiler than the other products use.)
This is strictly C code. The MSVC tag is a synonym for the Visual-C++ tag.