Only allow specific behavior in C ++?

Is it possible in gcc / g ++ or ms C ++ to set a flag that allows only certain behavior? so something like below gives me a warning or preferably an error

func(a++, a, ++a) 
+7
source share
5 answers

Undefined and unspecified behavior is so specifically designated in the standard, because it can cause an unjustified load on the implementation to diagnose all its examples (or it would be impossible to determine).

It was expected that the programmer would take care to avoid undefined areas.

For your stated example, it should be obvious to the programmer not to just write this code in the first place.

At the same time, g++ -Wall will catch some bad code, for example, the lack of return in non-void functions, to give one example.

EDIT: @sehe also indicates a -Wsequence-point that will catch this exact code construct, although there should be a sequence point between the evaluation of each argument (the order in which the arguments are evaluated is not defined, however).

+8
source

GNU C ++ has the following

  -Wsequence-point Warn about code that may have undefined semantics because of violations of sequence point rules in the C and C++ standards. 

This will correctly mark the call you made.

  -Wstrict-overflow -Wstrict-overflow -fstrict-aliasing -fstrict-overflow 

NTN

+7
source

Not. For example, consider the following:

 int badfunc(int &a, int &b) { return func(a++, b++); } 

This behavior is undefined if a and b have the same referand. In the general case, the compiler cannot know what arguments will be passed to the function, so it cannot reliably recognize this case of undefined behavior. Therefore, it cannot catch all undefined behavior.

Compiler warnings are used to identify some instances of undefined behavior, but not all.

In theory, you could write an implementation in C ++ that will conduct a huge number of checks at runtime to ensure that undefined behavior is always identified and treated in the ways defined by this implementation. It still wonโ€™t tell you at compile time (see: Stopping problem), and in practice, you will probably be better off with C #, which was designed to make the necessary runtime checks reasonably efficient ...

Even if you built this magic test of C ++ implementation, it still may not tell you what you really want to know, namely, whether your code is correct. Sometimes (hovering in your seats) is determined by the implementation whether the behavior is undefined. For a simple example, tolower((char)-1); defined the behavior [*] if char not specified, but undefined if char signed.

Thus, if your magic check does not do all the implementation options, like the โ€œrealโ€ implementation that you want your code to work for, it will not tell you if the code defined the behavior for the set of implementation options in the โ€œrealโ€ implementation, only if she defined the behavior for the implementation options made in the implementation of the magic check.

To find out that your code is correct and portable, you need to know (for starters) that it does not create undefined behavior for any set of implementation options. And, for that matter, for any input, and not just for the input used in your tests. You might think that this is a big flaw in C ++ compared to languages โ€‹โ€‹without undefined behavior. Of course, sometimes this is inconvenient and affects how you go about security software programs. In practice, however, in order for you to correctly evaluate your code, you do not just need it to determine the behavior, you need the behavior to match the specification document. This is a much more serious problem, and in practice it is more difficult to write an error in (say) Java or Python than in C ++. I wrote a lot of errors in all three, and knowing that in Java or Python the behavior was defined, but the wrong one did not help me with this.

[*] Well, the result is still determined by the implementation, it depends on the execution character set, but the implementation should return the correct result. If char signed, failure is allowed.

+3
source

It laughed great. Sorry, this did not mean any crime; this is a good question.

There is no compiler on the planet that allows only 100% specific behavior. This is the undefined nature of things that make it so heavy. There are many cases in the standard, but they are often too vague to be effectively implemented in the compiler.

I know that Clang developers showed some interest in adding this functionality, but they did not start as far as I know.

The only thing you can do now and in the near / future is to increase the level of warning and the severity of your compiler. Unfortunately, even in recent versions, MSVC is a pain in this regard. At warning level 4 and above, he will get some silly warnings that have nothing to do with the correctness of the code, and you often have to jump through hoops to get them to leave.

GCC is better in my personal experience. I personally use these options, providing the most rigorous checks (I know now)

 -std=c++0x -pedantic -Wextra -Weffc++ -Wmissing-include-dirs -Wstrict-aliasing 

Of course, I provide null warnings, if you want to do this, just add -Werror to the line above, and any error will fail. These are mainly std and pedantic , which ensure compliance with standard behavior, Wextra catches some unforeseen semi-errors.

And, of course, compile your code with different compilers (and make sure they diagnose the problem correctly by asking here where people know what the / standard says).

+2
source

As long as I agree with Mark's answer, I just thought I should let you know ...

 #include <stdio.h> int func(int a, int b, int c) { return a + b + c; } int main() { int a=0; printf("%d\n", func(a++, a, ++a)); /* line 11 */ return 0; } 

When compiling the code above using gcc -Wall , I get the following warnings:

 test.c:11: warning: operation on 'a' may be undefined test.c:11: warning: operation on 'a' may be undefined 

due to a++ and ++a , I suppose. To some extent this has been implemented. But, obviously, we cannot expect all undefined behavior to be recognized by the compiler.

+1
source

All Articles