First things you check for when you've got errors

M

Martin Wells

When I have errors in a program, whether they be compiler errors,
linker errors, or if the program crashes when running, I have a list
of things I check for initially.

If I get an error for something undeclared, the first thing I do is go
through my header files and check that the inclusion-guard macro is
specific to that header file. For instance, if the header file is
called "data.h", I make sure the inclusion guard is "H__DATA" and not
something like "H__GUI". The reason I have to check for this is that I
commonly copy-paste inclusion guards from one header file to another.

The program I'm currently developing was crashing when running, the
error being an invalid memory access. I went through the offending
function line-by-line and it wasn't long before I spotted the error. I
have a strong habit of writing the following:

char *p = data;
char const *const pover = data + sizeof data;

This habit was so strong that it led me to write:

unsigned *p = data;
unsigned const *const pover = data + sizeof data;

....when of course I should have written: + sizeof data/sizeof*data

So next thing I did was do a find for "sizeof" in every one of the
files to make sure I hadn't made the same error elsewhere.

What kind of things do you all check for initially when presented with
a certain kind of error? One thing I find helps greatly is turning off
implicit int and also implicit function declarations via the compiler
options.

Martin
 
B

Ben Pfaff

Martin Wells said:
What kind of things do you all check for initially when presented with
a certain kind of error?

Are you talking about syntax error type diagnostics? Usually the
cause of that kind of error is obvious when I look at the source
code line cited by the compiler.
One thing I find helps greatly is turning off implicit int and
also implicit function declarations via the compiler options.

Turning on lots of warnings can help, but I'd recommend using
them all the time, not just when you're trying to find some
particular source code error.
 
A

Army1987

The program I'm currently developing was crashing when running, the
error being an invalid memory access. I went through the offending
function line-by-line and it wasn't long before I spotted the error. I
have a strong habit of writing the following:

char *p = data;
char const *const pover = data + sizeof data;

This habit was so strong that it led me to write:

unsigned *p = data;
unsigned const *const pover = data + sizeof data;

...when of course I should have written: + sizeof data/sizeof*data
Wouldn't &data + 1 do the same thing?
-
Army1987 (Replace "NOSPAM" with "email")
A hamburger is better than nothing.
Nothing is better than eternal happiness.
Therefore, a hamburger is better than eternal happiness.
 
T

Tor Rustad

Martin said:
When I have errors in a program, whether they be compiler errors,
linker errors, or if the program crashes when running, I have a list
of things I check for initially.

It depends on the error...

For run-time errors, some are hard-to-find. If fault happened in test
environment, running the program in debugger is easy. Some bugs don't
happen in the debugger, or can't be reproduced. In such cases, I would
use a post-mortem debugger.

For cryptographic software, I'm not allowed to debug the production
environment. Hence, unless the error can be reproduced in TEST, one need
to read the source.

In some cases you don't have the source. I can remember one such bug in
embedded ROM software, which we located by looking at the binary, and
informed the vendor afterwards about the bug.


--
Tor <torust [at] online [dot] no>

"There are two ways of constructing a software design. One way is to
make it so simple that there are obviously no deficiencies. And the
other way is to make it so complicated that there are no obvious
deficiencies"
 
M

Malcolm McLean

Martin Wells said:
What kind of things do you all check for initially when presented with
a certain kind of error? One thing I find helps greatly is turning off
implicit int and also implicit function declarations via the compiler
options.
If a program segfaults that generally means that an array index or size has
been calculated incorrectly. The way that usually happens is that you have
two structures, one of which holds indices into the second. The second
structure is then revised, but the first not updated. So that's always my
first focus.

If you are good about always either destroying or setting invalid pointers
to null you will only occasionally get a sefault due to a wild pointer.
Normally you'll get a null pointer dereference, which is easy to find.

However if you get a really difficult bug, with wrong output popping up
seemingly from nowhere, probably it is due to a pointer pointing into memory
that you own but have reallocated for another purpose.

The important thing is to get to the bottom of a bug as soon as it crops up.
Not just make some change and breathe a sigh of relief when the problem goes
away. If it isn't obvious how the change fixed the bug, put it back and try
to reproduce the bug, and then track it down.
 
R

Richard Tobin

Martin Wells said:
If I get an error for something undeclared, the first thing I do is go
through my header files and check that the inclusion-guard macro is
specific to that header file.

When I get an error for something undeclared, usually I just
add "int i;" at the top of the procedure.

-- Richard
 
M

Martin Wells

Army1987:
Wouldn't &data + 1 do the same thing?


Good thinking. Only thing is that there's no implicit conversion from:

unsigned (*)[N]

to:

unsigned *

But I might start using:

unsigned const *const pover = (void*)(data+1);

Martin
 
K

Keith Thompson

Martin Wells said:
When I have errors in a program, whether they be compiler errors,
linker errors, or if the program crashes when running, I have a list
of things I check for initially.

If I get an error for something undeclared, the first thing I do is go
through my header files and check that the inclusion-guard macro is
specific to that header file. For instance, if the header file is
called "data.h", I make sure the inclusion guard is "H__DATA" and not
something like "H__GUI". The reason I have to check for this is that I
commonly copy-paste inclusion guards from one header file to another.
[...]

If I found myself running into that kind of error frequently,
I'd (a) define a consistent convention for inclusion guard macro
names, where the macro name is mechanically derivable from the file
name, (b) write a tool that examines a header file (or optionally
traverses a directory tree containing header files) and reports any
inconsistencies, and (c) invoke the tool automatically, either as
part of the build process or as part of the process that packages
the software for release.

The directory traversal, of course, can't be done in portable
standard C. If I wanted to insist on implementing the tool in
portable standard C, I'd feed it a list of file names (though it
probably would still have to know how to extract the file name
portion of a full path). But in practice, I'd write it in Perl.
 
S

santosh

Keith said:
Martin Wells said:
When I have errors in a program, whether they be compiler errors,
linker errors, or if the program crashes when running, I have a list
of things I check for initially.

If I get an error for something undeclared, the first thing I do is
go through my header files and check that the inclusion-guard macro
is specific to that header file. For instance, if the header file is
called "data.h", I make sure the inclusion guard is "H__DATA" and not
something like "H__GUI". The reason I have to check for this is that
I commonly copy-paste inclusion guards from one header file to
another.
[...]

If I found myself running into that kind of error frequently,
I'd (a) define a consistent convention for inclusion guard macro
names, where the macro name is mechanically derivable from the file
name, (b) write a tool that examines a header file (or optionally
traverses a directory tree containing header files) and reports any
inconsistencies, and (c) invoke the tool automatically, either as
part of the build process or as part of the process that packages
the software for release.

The directory traversal, of course, can't be done in portable
standard C. If I wanted to insist on implementing the tool in
portable standard C, I'd feed it a list of file names (though it
probably would still have to know how to extract the file name
portion of a full path).

Or perhaps make use of the 'basename' utility?
 
A

Army1987

Army1987:
Wouldn't &data + 1 do the same thing?


Good thinking. Only thing is that there's no implicit conversion from:

unsigned (*)[N]

to:

unsigned *

But I might start using:

unsigned const *const pover = (void*)(data+1);
You mean (void *)(&data + 1) ?
 
O

Old Wolf

When I have errors in a program, whether they be compiler errors,
linker errors, or if the program crashes when running, I have a list
of things I check for initially.

I read the error messages
 
M

Martin Wells

Old Wolf:
I read the error messages


ERROR: IsBigCan undeclared

Which part of your (unpretentious) genius tells you exactly what you
did wrong?

Is it naivety or attempted-show-off-ness that makes you post such
tripe? Or are you just a dickhead maybe?

Martin
 
N

Nick Keighley

Old Wolf:



ERROR: IsBigCan undeclared

Which part of your (unpretentious) genius tells you exactly what you
did wrong?

Is it naivety or attempted-show-off-ness that makes you post such
tripe? Or are you just a <deleted> maybe?

most compilers tell you which line the error is on. So go
and look at the line. I'd guess there was a mismatch between
the declaration and usage of IsBigCan. Either a spelling
mistake (it was supposed to be isBigCan). Or you missed it
out completely.

Normally compilers tell you pretty clearly what is wrong,
why not just fix it?

Do you always react that badly to criticism?
 
M

Martin Wells

Nick:
most compilers tell you which line the error is on. So go
and look at the line. I'd guess there was a mismatch between
the declaration and usage of IsBigCan. Either a spelling
mistake (it was supposed to be isBigCan). Or you missed it
out completely.

Normally compilers tell you pretty clearly what is wrong,
why not just fix it?

Do you always react that badly to criticism?


I hardly started this thread to deal with simple misspelling errors.
There are many kinds of error which the compiler won't point you to
the problematic line, particularly in the case of macro expansion.
Also, if you get an "undeclared" error, the compiler won't tell you if
one of your inclusion guards is wrong.

Martin
 
O

Old Wolf

Old Wolf:


ERROR: IsBigCan undeclared

Which part of your (unpretentious) genius tells you exactly what you
did wrong?

I've never used a compiler that doesn't report the file
and line number of the error. I suggest you figure out the
switches to pass to your compiler in order to procure this
information. (Out of interest, what is the compiler that
produces that message?)
Is it naivety or attempted-show-off-ness that makes you post such
tripe? Or are you just a dickhead maybe?

I can't think of a sane reason why you would attempt
some sort of generic code analysis, instead of
following the trail begun by the compiler diagnostic.
 

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

Forum statistics

Threads
474,262
Messages
2,571,050
Members
48,769
Latest member
Clifft

Latest Threads

Top