3

Is an implementation allowed to issue a diagnostic message for a well-formed program?

For example some compilers issue a warning about unused expression result when compiling the following well-formed program:

int main() { 0; }

Are such compilers allowed to consider that warning a diagnostic message?

Supremum
  • 542
  • 7
  • 23
  • Similar to [Should a diagnostic be emmited for discarded value expressions that do not have side effects?](http://stackoverflow.com/q/24996606/1708801) – Shafik Yaghmour Jul 28 '15 at 16:29

2 Answers2

4

It's perfectly fine to issue a diagnostic, as long as the rules below are met in any corresponding scenario. §1.4/2:

Although this International Standard states only requirements on C ++ implementations, those requirements are often easier to understand if they are phrased as requirements on programs, parts of programs, or execution of programs. Such requirements have the following meaning:

  • If a program contains no violations of the rules in this International Standard, a conforming implementation shall, within its resource limits, accept and correctly execute that program.

  • If a program contains a violation of any diagnosable rule or an occurrence of a construct described in this Standard as “conditionally-supported” when the implementation does not support that construct, a conforming implementation shall issue at least one diagnostic message.

  • If a program contains a violation of a rule for which no diagnostic is required, this International Standard places no requirement on implementations with respect to that program.

"Accepting" solely addresses the acknowledgment of the implementation that this is a well-formed program, not the absence of any diagnostics. After all, despite any warnings issued in the process, implementations still yield the object file you asked for.

However, there is one rule concerning templates that does require that there be no diagnostic issued; §14.6/8:

No diagnostic shall be issued for a template for which a valid specialization can be generated.

Columbo
  • 60,038
  • 8
  • 155
  • 203
  • 1
    "No diagnostic shall be issued for a template for which a valid specialization can be generated." I think that is a defect of the c++ standard. I think they just mean that just because some specialisations would be ill-formed, doesn't mean that the template is ill-formed. – Supremum Jul 28 '15 at 17:17
  • 1
    @Supremum [Yep](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1785). At least to some extent. – Columbo Jul 28 '15 at 17:21
3

An implementation can issue (1)any number of diagnostics it wants, as long as it does issue the required diagnostics.

It must accept correct programs, to the degree that it's able to,

C++14 §1.4/2:

If a program contains no violations of the rules in this International Standard, a conforming imple- mentation shall, within its resource limits, accept and correctly execute that program"

but it can issue diagnostics about it.

The C++ standard does not differentiate between error messages and warning messages, but this is a de facto standard. An error message means (by convention) that no binary is produced, because the problem is too severe. A warning message means (by convention) that there is a potential problem, but not a direct violation of language rules, and so a binary is produced unless there are also errors.


Sometimes the lines are a bit blurred, where implementations incorrectly but for pragmatic reasons accept invalid code, with only warnings or even no diagnostics. For new code one may therefore ask the compiler to treat every warning as an error, and aim for completely clean compiles. And as I understand it that's now absolutely not uncommon.

With some compilers, e.g. Visual C++, it can however be problematic, because the compiler issues too many silly-warnings, warnings about perfectly legitimate and non-problematic constructs. Then one has to somehow suppress those warnings. E.g. via #pragma directives, if possible, or by code rewrites.

Happily for Visual C++ there exists a header with such #pragma directives that turn off sillywarnings, compiled about five years ago from a community effort in the comp.lang.c++ Usenet group. And happily, for the community edition of Visual Studio 2015 there is an extension that provides a project template with that header included. These are both by me.


For the code in question,

int main() { 0; }

… instead of suppressing the warning, which generally is a useful one, you should rewrite the code to express your intent explicitly:

int main() { (void)0; }

The (void) cast tells the compiler that it's your intent to discard the value of that expression.

In the case of using this construct for an otherwise unused function argument, you can additionally declare an incomplete class of the same name, to prevent inadvertent use of the name:

(void)arg_name; struct arg_name;

But since it's unconventional it may trip up other programmers – with the compilers I use the error message for later use of the name is not exactly intuitive.


(1) Except as noted by Columbo in his answer, C++14 §14.6/8 “No diagnostic shall be issued for a template for which a valid specialization can be generated.”.

Community
  • 1
  • 1
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • According to [intro.compliance] (http://eel.is/c++draft/intro#intro.compliance-8) it is ok for an implementation to accept ill-formed programs as long as it gives diagnostic for it. You say: "Sometimes the lines are a bit blurred, where implementations incorrectly but for pragmatic reasons accept invalid code, with only warnings or even no diagnostics.". Accepting such code with only warnings is ok. Without diagnostics is not ok, that sound like a bug that should be reported. Do you have any example of that case? – Supremum Jul 28 '15 at 16:41
  • @Supremum: the simplest example is probably `void main`. – Cheers and hth. - Alf Jul 28 '15 at 16:43
  • Clang and gcc both gives errors for void main() {} Visual studio c++ does not give any diagnostics. If visual studio c++ wants to have this as a language extension it should issue at least one diagnostic message (by convention a warning) and then it could still accepts it. This is a bug in visual studio c++, I think you should report it. Maybe there are some options that make visual studio c++ standard compliant however? – Supremum Jul 28 '15 at 16:54
  • @supremum: As far as I know there's no option to get a diagnostic for `void main` from Visual C++, as of the 2015 version. But then that compiler does have some undocumented options. E.g., it supports, but claims deprecation, the ordinary `-o` output option that other compilers accept. – Cheers and hth. - Alf Jul 28 '15 at 17:04
  • What I find a bit confusing when testing compilers is that by convention there are two types of warning messages but they look the same. The first type are warnings about compiler extensions and they are diagnostics messages that are required because of ill-formed programs. The second type are warnings that are given for well-formed programs (and they are diagnostics messages that are not required to be issued). They indicate possible mistakes by the programmer. Because of this I stared to use -std=c++XX -pedantic-errors with gcc and clang. Then the first type of warnings becomes errors. – Supremum Jul 28 '15 at 17:06
  • About foot note (1). This seems to be a defect in the c++ standard. See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1785 – Supremum Jul 28 '15 at 17:49
  • @Cheersandhth.-Alf: Doesn't `/Za` produce `warning C4326: return type of 'main' should be 'int' instead of 'void'` anymore in VC++ 2015? It should, according to https://msdn.microsoft.com/en-us/library/1wk7h414.aspx – Christian Hackl Jul 28 '15 at 18:44
  • @Supremum: As you can see, you just don't use a C++ compiler with default settings, no matter if it's gcc, clang or VC++. You will always need to use some compiler options to get the desired behaviour. The VC++ compiler option you are looking for is `/Za`. You cannot use it for compilation units which need ``, though. My personal preference for VC++ projects is to enable `/Za` by default and disable it specifically for those compilation units where it causes compiler errors. – Christian Hackl Jul 28 '15 at 18:56
  • @ChristianHackl: Yes you're right, but yet … not. I didn't try that or even think about it because `/Za` is known to produce a diagnostic avalanche, including *errors*, for standard library and system headers. As indeed it did now just by including ``, i.e., it renders the compiler unusable for anything but toy examples that don't include any headers. – Cheers and hth. - Alf Jul 28 '15 at 21:47
  • @Cheers and hth. - Alf: But you can set the flag per compilation unit, and, depending on what kind of project you are dealing with, will not need in many or most of them. At least that has been my experience so far. – Christian Hackl Jul 29 '15 at 05:23
  • As far as standard library headers are concerned, I am not aware of any /Za-related problem with them. – Christian Hackl Jul 29 '15 at 05:26
  • @CristianHackl: Well I got an avalanche of warnings on ``. It was the only one I tried (before ``). – Cheers and hth. - Alf Jul 29 '15 at 08:57