1

Microsoft's MIDL compiler generates C/C++ source code files that are slightly invalid, like the code in this extract:

#ifndef CLSID_DEFINED
#define CLSID_DEFINED
typedef IID CLSID;
#endif // CLSID_DEFINED

#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
        const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}

#endif !_MIDL_USE_GUIDDEF_

The tokens after #endif are ignored by Visual C++, but the Holy Standard require nothing there, and so g++ errs out, and even gcc (compiling as C) yields a warning:

H:\dev\tools\better keyboard\test>gcc com_server\com_server_i.c -c
com_server\com_server_i.c:68:8: warning: extra tokens at end of #endif directive
 #endif !_MIDL_USE_GUIDDEF_
        ^

H:\dev\tools\better keyboard\test>_

It gets tiresome and annoying to manually fix up that code each time that it's generated.

Is there some better way to avoid this apparently unnamed warning, assuming that gcc must compile the code?

I have looked at an existing question roughly about this, but to no avail.

Community
  • 1
  • 1
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • 2
    Post-process the generated code: `sed -i .bak -e 's/^#endif .*/#endif/' com_server/com_server_i.c` or equivalent. Or you can preserve the material after the `#endif` but put a comment there: `sed -i .bak -e 's%^#endif \(.*\)%#endif // \1%' com_server/com_server_i.c`. – Jonathan Leffler Mar 19 '15 at 19:54
  • The x-ref'd question won't readily help; the `!` cannot be removed by macro definition. Actually, the presence of a macro after the `#endif` elicits the warning even if the macro expands to nothing. I note that the opening `#if` or `#ifdef` or `#ifndef` for the objectionable `#endif` is not shown in the question. Have you checked the Microsoft bug reports for the MIDL compiler? And the options to the MIDL compiler? – Jonathan Leffler Mar 19 '15 at 19:59
  • The opening `#if` is just `#ifdef _MIDL_USE_GUIDDEF_`. No I haven't checked bug reports. The MIDL options include options to support Microsoft IDL and C language extensions in the IDL, but AFAICS none to turn off language extensions anywhere. Thanks for the post-processing suggestion. I think I'll do that! :) – Cheers and hth. - Alf Mar 19 '15 at 20:04

1 Answers1

3

Converting comments into an answer.

The simplest mechanism is probably to post-process the generated code:

sed -i.bak -e 's/^#endif .*/#endif/' com_server/com_server_i.c

or equivalent. Or you can preserve the material after the #endif but put a comment there:

sed -i.bak -e 's%^#endif \(.*\)%#endif // \1%' com_server/com_server_i.c

If you're using a makefile, it is pretty easy to add the post-processing as an extra operation after the invocation of the MIDL compiler.

The cross-referenced question won't readily help; the ! cannot be removed by macro definition. Actually, the presence of a macro after the #endif elicits the warning even if the macro expands to nothing.

Have you checked the Microsoft bug reports for the MIDL compiler (to see whether it is a known problem that they decline to fix)? And have you checked the options to the MIDL compiler to see if there's anything that would fix this?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • I should just note here that the default Solaris `sed` doesn't support `-i`. – Mark B Mar 19 '15 at 20:19
  • @MarkB: that's where the 'or equivalent' kicks in. GNU `sed` would allow no suffix after the `-i` (but requires the `.bak` to be attached to the `-i`, as in `-i.bak`); BSD (Mac OS X) `sed` requires an argument such as `.bak` with `-i`. The notation used works with both. Clearly, the code can create another file name based on the source name and then move/copy the result over the `.c` file; that would be the equivalent to use on Solaris and other more traditional Unix systems. – Jonathan Leffler Mar 19 '15 at 20:28
  • The `sed` I have by default is a MinGW Windows port of GNU `sed`. It reports that it has the `-i` option, and supports backup file extension. In the Windows command line I had to replace the single quote with double quotes, but other than that both commands given worked nicely (well except the last one effectively replaces `//` with `// //`, but no matter :) ). – Cheers and hth. - Alf Mar 19 '15 at 21:47
  • Hmm...yes, if you already have `//` comments after `#endif`, then the script doubles them up, but the compiler won't care. The worst scenario would be a multi-line `/*` comment starting on the `#endif`; that would be converted to a single-line comment, so the comment on the second and subsequent lines would be misinterpreted as code. It's probably best to delete such comments in the first place, or move the start line after the `#endif` line. – Jonathan Leffler Mar 19 '15 at 21:50