assert must take int?

  • Thread starter Tomás Ó hÉilidhe
  • Start date
R

Richard Tobin

Richard Heathfield said:
A failing assertion indicates a broken program. The proper solution is for
your testers to have a complete list of assertions, and to arrange
white-box tests that fire those assertions if it is at all possible. If
they *can* fire the assertions, they reject the code.

But surely the main use of assertions is for situations where you
believe there *isn't* any way for them to fail, but (not being
perfect) recognise that you might be mistaken. They help you find and
solve bugs you didn't know how to test for.

-- Richard
 
R

Richard Heathfield

Harald van D?k said:
If it's not a prototype, how does it require the expression to be an int?

First of all, let's establish that it is *not* a prototype. A prototype is
a function declaration that lists the types of its parameters. Since
assert is required to be a macro, it cannot be a function. Therefore, it
does not have a prototype. The best that can be said for the above is that
it is an illustration of what the prototype /would/ be if assert /were/ a
function. All it really tells us is that assert is a macro that yields no
value but which does require an expression, and it handily tells us the
type of the required expression, which is int. Since the Standard doesn't
define what happens if you give it some other expression type, the
behaviour is undefined if you do that.
 
R

Richard Heathfield

Richard Tobin said:
But surely the main use of assertions is for situations where you
believe there *isn't* any way for them to fail, but (not being
perfect) recognise that you might be mistaken.

Yes, of course. So the testers will have to be creative, right?
They help you find and
solve bugs you didn't know how to test for.

Right. But your testers will find a way, if they're any good.

(Incidentally, I'm sure you know this, but I suspect many people /don't/
realise that there really are people who do testing as a full-time job;
not all organisations have dedicated testers, but many do - and it is just
as skilled a job as programming, if not more so, when done properly.)
 
F

Flash Gordon

Richard Heathfield wrote, On 09/12/07 07:29:
Harald van D?k said:


Sure,

Surely wrong you mean. There is no implicit conversion from pointer to
int, so if there was a prototype and you passed a pointer the compiler
would be required to reject the program.
but it isn't a prototype, is it? Yes, it don't 'arf look like one,
but it's really a macro in disguise. Writing it in prototype form was,
IMO, a mistake.

Possibly, but it was certainly an easy way to express it.
So no, there is no implicit conversion to int.

There never is anyway.

Of course, you can always write your own macro...
#defined my_assert(x) assert((x)!=0)
Then you can provide my_assert anything that can legally be compared
against 0, including pointer and floating point expressions.
 
R

Richard Heathfield

Flash Gordon said:
Richard Heathfield wrote, On 09/12/07 07:29:

Surely wrong you mean. There is no implicit conversion from pointer to
int,

No, but there are implicit conversions from other expression types, e.g.
char, short, and so on, which is probably what I was thinking of when I
said "sure". Clearly you're right about pointers, though. (I must confess
that I do not always re-read an entire thread when posting a reply to a
particular point. My reply addressed the exact sentence quoted above, and
wasn't overly concerned with the upthread pointery thingy.)
so if there was a prototype and you passed a pointer the compiler
would be required to reject the program.
Yes.


Possibly, but it was certainly an easy way to express it.

Well, quite so - which is obviously why they did it.
There never is anyway.

Except sometimes! :)
 
M

Malcolm McLean

RoS said:
i disagree
i cancelled all NULLs because the C[++?] compiler not compiled
some one of these (don't know why)
You've got to include at least one header from the standard library to get
NULL defined.
Personally I prefer raw zeroes as well. The caps give NULL a visial emphasis
it ususally doesn't deserve.
 
R

Richard Tobin

Richard Heathfield said:
(Incidentally, I'm sure you know this, but I suspect many people /don't/
realise that there really are people who do testing as a full-time job;
not all organisations have dedicated testers, but many do

And even if all organisations did, not all software is written by
organisations. Much is written by individuals with little if any
support, even if they are working for some organisation at the time.

Most of the programs I write, some of which are used by thousands of
people, are regarded as mere side-effects of fulfilling the research
contracts that fund us. At best they are regarded as a slightly
dubious kind of publication. I release them to other people because
they're useful and it helps make us well-known among people in our
research area, but the idea that the someone might pay us to test our
software is laughable. In effect, the users are the testers.

-- Richard
 
H

Harald van Dijk

Harald van D?k said:

First of all, let's establish that it is *not* a prototype. A prototype
is a function declaration that lists the types of its parameters. Since
assert is required to be a macro, it cannot be a function. Therefore, it
does not have a prototype. The best that can be said for the above is
that it is an illustration of what the prototype /would/ be if assert
/were/ a function.

Agreed, but...
All it really tells us is that assert is a macro that
yields no value but which does require an expression, and it handily
tells us the type of the required expression, which is int.

....is there anything in C90 that supports this idea? You're saying that
void assert(int expression);
has a meaning that differs in important areas from the exact same syntax
used to declare a function named assert, that since it isn't a prototype,
it shouldn't be read as one. Yet at the same time you're saying this
prototype-lookalike *should* be read as a prototype when determining the
accepted type of the macro argument. I would expect the conclusion to be
that the prototype-lookalike should be ignored entirely. Why is that not
so?
 
H

Harald van Dijk

Richard Heathfield wrote, On 09/12/07 07:29:

Surely wrong you mean. There is no implicit conversion from pointer to
int, so if there was a prototype and you passed a pointer the compiler
would be required to reject the program.

I used assert(0.5) as my example, and there is an implicit conversion
from double to int.
 
G

Golden California Girls

Richard said:
Golden California Girls said:


I tried this, and got "the number you have dialled has not been
recognised".

You must have forgotten to dial 6 to get a headquarters line. :)
Assuming we can fix that problem, some people will be using
the program in situations where they can't use the phone (either because
it's against the rules that apply in their place of work or simply because
there isn't a phone immediately to hand), so the advice doesn't work for
them.

There are different standards for programs that are going to be released to the
public and programs that will only be used inside an organization. Big head
honcho types frequently require code to be usable at a specific time and that
may not leave time to put in place nice pretty error messages for everything
that might go wrong. It doesn't mean you don't test for it.
A failing assertion indicates a broken program.

You are assuming the thing being tested is the program logic. Not always the
case. Consider assert(rate_of_pay > 0) in a section of a system of programs
where checks are being cut and the programmer knows that the section (possibly
in another program) where the input of rate_of_pay happens it is tested to be
positive. The user (operator) isn't going to solve this one no matter what
message gets printed and for security reasons you need to get higher up people
involved. Dumping a cryptic assert message isn't wrong in this case. For
security you may not even want the operator to know why it failed. You want to
make them pick up the phone or go see someone in person.
 
R

Richard Heathfield

Golden California Girls said:
Richard Heathfield wrote:


You are assuming the thing being tested is the program logic.
Correct.

Not always the case.

Also correct, because some people misuse assertions.
Consider assert(rate_of_pay > 0) in a section of a system of
programs where checks are being cut and the programmer knows that the
section (possibly in another program) where the input of rate_of_pay
happens it is tested to be positive.

This may or may not be a program logic error, and it's impossible to tell
without seeing more of the program. If, at this point in the program, it
is "impossible" for that object to have a non-positive value, then the
assertion is appropriate. If this is mere data validation, the assertion
is inappropriate; rather, the normal runtime error processing subsystem
for the program should be invoked.
The user (operator) isn't going to solve this one no matter
what message gets printed

Right. Nevertheless, if this is data validation, the error should be
reported as suggested above. If this is a program logic error, then it
should be revealed during testing. Yes, I know that testing cannot
guarantee the absence of bugs. But a white-box tester should view an
assertion as a challenge ("betcha you can't make this happen"), and should
strive to be equal to that challenge.

<snip>
 
C

CBFalconer

Richard said:
Golden California Girls said:
.... snip ...


This may or may not be a program logic error, and it's impossible
to tell without seeing more of the program. If, at this point in
the program, it is "impossible" for that object to have a non-
positive value, then the assertion is appropriate. If this is
mere data validation, the assertion is inappropriate; rather, the
normal runtime error processing subsystem for the program should
be invoked.

Normally I would consider that a programming error. However, it is
possibly that the firm is selling play time in its operations.
This may lead to confusion with tax rates, etc. :)

I suspect various firms with which I deal of this. Explains much.
 
P

Peter Nilsson

Ben Bacarisse said:
Yes, in C89 the prototype is for an int. In C99 this
has been changed to any scalar expression (of course
you can't write that as a prototype but that is the
implementation's problem, not yours).

Since it's a macro, not a function, it's not much of
a problem for most implementations; just replace
expansion instances of the parameter p (say) with
((p) != 0).
 
K

Keith Thompson

Harald van Dijk said:
Agreed, but...


...is there anything in C90 that supports this idea? You're saying that
void assert(int expression);
has a meaning that differs in important areas from the exact same syntax
used to declare a function named assert, that since it isn't a prototype,
it shouldn't be read as one. Yet at the same time you're saying this
prototype-lookalike *should* be read as a prototype when determining the
accepted type of the macro argument. I would expect the conclusion to be
that the prototype-lookalike should be ignored entirely. Why is that not
so?

The description of assert() in C90 was flawed. That standard used
something that looks like a prototype to illustrate how the assert
macro is to be used, but since it's required to be a macro, there's no
reasonable definition of assert() that would maintain the full
semantics required if it were a prototyped function (particularly the
implicit declaration to int for an argument of any arithmetic type).
Because of this, it's very difficult to argue that the behavior of
assert() with, say, a floating-point argument was well defined.

C99 improved the definition by providing a pseudo-prototype:

void assert(scalar expression);

Because it can't be a real prototype, we're left with the idea that it
can accept any arbitrary scalar expression; the description is also
clearer.

It's quite possible that all existing C90 implementations of assert()
work as expected for non-int scalar arguments (the most
straightforward implementation would work that way; you'd have to
expend extra effort to make non-int expressions fail). But since the
C90 standard didn't guarantee this, it was safest not to depend on it.

Replacing ``assert(expr)'' with ``assert(expr != 0)'' would suffice to
force the argument to be of type int, making the invocation safe.
 
M

Malcolm McLean

Richard Heathfield said:
Golden California Girls said:


Also correct, because some people misuse assertions.
I sometimes assert() mallocs().
It is lazy habit.
 
J

jaysome

[snip]
It's quite possible that all existing C90 implementations of assert()
work as expected for non-int scalar arguments (the most
straightforward implementation would work that way; you'd have to
expend extra effort to make non-int expressions fail). But since the
C90 standard didn't guarantee this, it was safest not to depend on it.

The same could be said about all existing C90 implementations working
with "void main". Like it or not, that's how it is, or seems to be.
Nevertheless, "int main" is preferred.

Can anyone cite a C90 implementation that accepts "void main" (i.e.,
compiles and links, with or without warnings) and results in undefined
behavior? And as far as undefined behavior is concerned, I'm talking
about the nasty kind that makes your computer smoke or formats your
hard drive or even starts WWIII.
 
R

Richard Bos

jaysome said:
Can anyone cite a C90 implementation that accepts "void main" (i.e.,
compiles and links, with or without warnings) and results in undefined
behavior? And as far as undefined behavior is concerned, I'm talking
about the nasty kind that makes your computer smoke or formats your
hard drive or even starts WWIII.

That's a rather restrictive kind of "undefined behaviour" you're
demanding, then. Unpredictably breaking compile processes because make
receives random values isn't good enough for you any more? Programs
simply crashing won't pull it these days?

Richard
 

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

Staff online

Members online

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top