C++ code verification

Y

Yossi Kreinin

Hi!

Is there a summary of the rules C++ code should obey, but an implementation
doesn't have to verify it does? For example, the one definition rule or
the prohibition to dereference a null pointer. Such a summary could be
extracted from the standard, perhaps it already was?

There are also a lot of tools looking for SOME of such violations. Is there a tool
that could guarantee something like: "ALL compile-time violations will be spotted,
unless made by object code (and not source code); and at run-time, ANY violation
which actually occurs will be detected (but there might still be uncovered
cases of such violations)"? Is there something making it impossible?

In particular, is there a boundary checker which detects ALL boundary errors
(and not only when: uninitialized memory is read/the objects are on the heap/
arrays with length known at compile time are used/combinations of such)?

Thanks in advance!
Yossi
 
J

JKop

Yossi Kreinin posted:
Hi!

Is there a summary of the rules C++ code should obey, but an
implementation doesn't have to verify it does? For example, the one
definition rule or the prohibition to dereference a null pointer. Such
a summary could be extracted from the standard, perhaps it already was?

There are also a lot of tools looking for SOME of such violations. Is
there a tool that could guarantee something like: "ALL compile-time
violations will be spotted, unless made by object code (and not source
code); and at run-time, ANY violation which actually occurs will be
detected (but there might still be uncovered cases of such
violations)"? Is there something making it impossible?

In particular, is there a boundary checker which detects ALL boundary
errors (and not only when: uninitialized memory is read/the objects are
on the heap/ arrays with length known at compile time are
used/combinations of such)?

Thanks in advance!
Yossi

Now that would be a handy tool! I've never seen the likes
of it.

-JKop
 
D

Derrick Coetzee

Yossi said:
Is there a tool that could guarantee something like: "ALL compile-time
violations will be spotted, unless made by object code (and not
source code); and at run-time, ANY violation which actually occurs
will be detected [ . . . ]

First of all, your "compile-time violations" statement is rather
difficult to interpret. In fact, almost all errors can be detected at
compile-time, but tools such as theorem-provers that establish this are
very sophisticated and require extensive user knowledge and user input.
Most errors that are easy to detect automatically already trigger
warnings on your favourite compiler. Static analysis is also limited in
C++ because many C++ programs tend to assume that many infrequent bad
things, such as I/O failing or integers overflowing, just doesn't happen
(so they're not correct, but work anyway almost all the time).

On the other hand, adding run-time checks that detect all triggering of
undefined or unspecified behaviour is entirely possible. Detecting
implementation-defined behaviour, however, proves of questionable value,
since a great deal of C++ programs, often not intended to be entirely
portable, depend in some critical way on implementation-defined
behavior, such as endianness or the size of an integer.

As for existing tools, there's not much to speak of, especially compared
to Java. With gcc, you can try the -fmudflap (which "instrument all
risky pointer/array dereferencing operations, some standard library
string/heap functions, and some other associated constructs with
range/validity tests") or link with the run-time library Electric Fence.
Also, exploit your compiler's ability to detect errors by encoding as
much information as you can in types - be very specific about what types
are required, and make many of them with fine granularity.

I hope this helps.
 
Y

Yossi Kreinin

Derrick Coetzee said:
Yossi said:
Is there a tool that could guarantee something like: "ALL compile-time
violations will be spotted, unless made by object code (and not
source code); and at run-time, ANY violation which actually occurs
will be detected [ . . . ]

First of all, your "compile-time violations" statement is rather
difficult to interpret. In fact, almost all errors can be detected at
compile-time, but tools such as theorem-provers that establish this are
very sophisticated and require extensive user knowledge and user input.
Most errors that are easy to detect automatically already trigger
warnings on your favourite compiler. Static analysis is also limited in
C++ because many C++ programs tend to assume that many infrequent bad
things, such as I/O failing or integers overflowing, just doesn't happen
(so they're not correct, but work anyway almost all the time).

For production code, I tend to rely on myself when it comes to overflow
or I/O, but I would like to have a tool that verifies the sanity of the
build, for instance, that an entity is not defined twice (due to conditional
compilation or alignment settings or such) and all template specializations
are seen where they should be, etc. Theorem-provers verifying stuff
beyond these basic language invariants are a different story.
On the other hand, adding run-time checks that detect all triggering of
undefined or unspecified behaviour is entirely possible. Detecting
implementation-defined behaviour, however, proves of questionable value,
since a great deal of C++ programs, often not intended to be entirely
portable, depend in some critical way on implementation-defined
behavior, such as endianness or the size of an integer.

In such cases, the warnings issued by a verification tool could be
supressed. At times, however, such assumptions are made without intent,
and sometimes make no sence, like dependancy on parameter evaluation order.
Then, when a compiler is upgraded, it takes weeks to debug such stuff,
and you are never sure if you are done.
As for existing tools, there's not much to speak of, especially compared
to Java.

For linux/x86, there is valgrind, which detects uninitialized memory
access and memory leaks. I think it is "worth speaking of" beacuse IMO
it GUARANTEES detection of such errors on optimized production code.
With gcc, you can try the -fmudflap (which "instrument all
risky pointer/array dereferencing operations, some standard library
string/heap functions, and some other associated constructs with
range/validity tests") or link with the run-time library Electric Fence.


My gcc has no -fmudflap (which version should have it?). Also, altering the
code generation may hide bugs by itself, but it could still help...
Electric Fence is presumably useless when a bug doesn't violate heap block
bondaries, am I right?
Also, exploit your compiler's ability to detect errors by encoding as
much information as you can in types - be very specific about what types
are required, and make many of them with fine granularity.

Thanks for a good advice, static typing may be very beneficial.
But when 10 or 20 people cooperate in a single project, a lot of
time they are debugging each other's bugs, and they may have different styles.
So it really, really helps to have AUTOMATIC detection of language invariants
violation, before the state of a process is corrupted to such an extent
that a debugger is completely useless. Even if that means the code
runs 10 or 20 times slower, like under valgrind.
I hope this helps.

Thanks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top