question about k&r2

A

Anthony Irwin

Hi all,

I have been going through the k&r2 book and all the examples are done
with main() instead of int main(void) and k&r2 in the start of chapter
1 does not return 0 so I haven't yet either.

I did two compiles shown below.

$ gcc -std=c89 -Wall exercise_1-9.c -o exercise_1-9
exercise_1-9.c:5: warning: return type defaults to `int'
exercise_1-9.c: In function `main':
exercise_1-9.c:27: warning: control reaches end of non-void function

$ gcc -std=c99 -Wall exercise_1-9.c -o exercise_1-9
exercise_1-9.c:5: warning: return type defaults to `int'


Why doesn't k&r2 have the int return type on main and why doesn't c99
care that I reached the end of a non-void function without returning a
value.

Kind Regards,
Anthony Irwin
 
R

Richard Heathfield

Anthony Irwin said:
Why doesn't k&r2 have the int return type on main

They rely on the fact that, if a function doesn't explicitly return any
type, it is assumed to return int. This is, in my opinion, poor style.
and why doesn't c99
care that I reached the end of a non-void function without returning a
value.

It does, normally - but they (foolishly?) made a special case for main.
 
A

Anthony Irwin

Richard said:
Anthony Irwin said:




They rely on the fact that, if a function doesn't explicitly return any
type, it is assumed to return int. This is, in my opinion, poor style.




It does, normally - but they (foolishly?) made a special case for main.

Ok thanks for the clarification. I will continue my way through the
k&r2 book which is definately a good book the sample programs they get
you to write seem more real some how, its hard to explain.

Thanks to all who recommended it as I would not have bought it if it
wasn't recommended so much here. Funny how one assumes that a smaller
book won't be as good as a bigger one.

Another quick question is var1 = var2 = var3 = var4 = 0; considered
good style to save typing. I saw it in k&r2 and it was a new concept
for me and I have used it a few types already.

Kind Regards,
Anthony Irwin
 
R

Richard Heathfield

Anthony Irwin said:
Another quick question is var1 = var2 = var3 = var4 = 0; considered
good style to save typing. I saw it in k&r2 and it was a new concept
for me and I have used it a few types already.

It's a handy shortcut. I would not recommend using it in too complicated
a way. For example, if you end up typing: a = b += c * a / d = e % f;
then you've probably gone too far.
 
C

CBFalconer

Anthony said:
.... snip ...

Another quick question is var1 = var2 = var3 = var4 = 0;
considered good style to save typing. I saw it in k&r2 and it
was a new concept for me and I have used it a few types already.

Opinions vary. I like it for various reasons. It emphasizes that
those items are initially equal. It may enable more efficient code
to be generated. It minimizes vertical space used.
 
P

pete

Anthony Irwin wrote:
Another quick question is var1 = var2 = var3 = var4 = 0; considered
good style to save typing.

Saving typing is a valid reason for writing code in a certain way,
but it is the weakest of all valid reasons.

The rule is that for the above c code statement,
the assigment of the zero value may be assigned to the vars
in any order. So, make sure to use that kind of code construct,
only when the order of the assignments doesn't matter.

If this is what you mean:
p -> next = q;
p = q;
don't write it this way:
p = p -> next = q;
 
A

Army1987

Anthony Irwin said:
Why doesn't k&r2 have the int return type on main and why doesn't c99 care
that I reached the end of a non-void function without returning a value.

C99 says that the closing brace of the main() function acts as return 0;},
or something like that (5.1.1.2.3.1).
 
C

coder

pete said:
Saving typing is a valid reason for writing code in a certain way,
but it is the weakest of all valid reasons.

The rule is that for the above c code statement,
the assigment of the zero value may be assigned to the vars
in any order. So, make sure to use that kind of code construct,
only when the order of the assignments doesn't matter.

If this is what you mean:
p -> next = q;
p = q;
don't write it this way:
p = p -> next = q;
What's wrong with the above line? I thought that the assignment
operator has right-left associativity.
 
D

Default User

CBFalconer said:
Opinions vary. I like it for various reasons. It emphasizes that
those items are initially equal. It may enable more efficient code
to be generated. It minimizes vertical space used.

I'm in the opposite camp. I've never used it in code. I generally feel
that variables that need initialization should be done at declaration
time, and I try to use an individual line for most variable
declarations.




Brian
 
C

CBFalconer

pete said:
Anthony Irwin wrote:
.... snip ...

If this is what you mean:
p -> next = q;
p = q;
don't write it this way:
p = p -> next = q;

No reason not to. Same effect.
 
C

Craig Franck

Opinions vary. I like it for various reasons. It emphasizes that
those items are initially equal. It may enable more efficient code
to be generated. It minimizes vertical space used.

True, but most modern compilers can optimize away whitespace
and carriage returns.
 
P

Peter Nilsson

Richard Heathfield said:
Anthony Irwin said:

They rely on the fact that, if a function doesn't explicitly
return any type, it is assumed to return int. This is, in my
opinion, poor style.

It may be a poor language 'feature', but I don't see it as
poor style.

Prior to standardisation, there was no void keyword. It makes
_more_ sense to leave out an explicit int than to put one in for
a function that doesn't return a value.

Of course, K&R2 was supposed to be about the (then) new standard,
but the fact remains the new standard was heavily backwards
compatible.
It does, normally - but they (foolishly?)

(Paul Psieh influence?)
made a special case for main.

The main function is not special cased in that regard.

There is still no requirement in C99 for a non-void function
to return a value. If the calling function attempts to use
a value from a non-void function that doesn't return a value
the behaviour is undefined. But unlike C++, a non-void function
failing to return a value is not, in and of itself, UB.

If you're talking about the default return value for main,
then I don't see that as being foolish if it strengthens
the robustness of otherwise sloppy programs without having
any adverse impact on C.
 
R

Richard Heathfield

Peter Nilsson said:
(Paul Psieh influence?)

Not exactly, no - I actually have a great deal of respect for the ISO
folks - but I do think this particular decision was foo... well,
ill-advised, anyway.
The main function is not special cased in that regard.

There is still no requirement in C99 for a non-void function
to return a value.

Ah, you are correct. My apologies. I'm just so accustomed to gcc's
diagnostic message (in other people's code!) that I got kerfuffled for
a moment there.

If you're talking about the default return value for main,
then I don't see that as being foolish if it strengthens
the robustness of otherwise sloppy programs without having
any adverse impact on C.

I guess I'm just one of those people who think that programmers ought to
do The Right Thing, and that their compilers should help to persuade
them so to do. :)
 
R

Richard Tobin

Opinions vary. I like it for various reasons. It emphasizes that
those items are initially equal. It may enable more efficient code
to be generated. It minimizes vertical space used.
[/QUOTE]
True, but most modern compilers can optimize away whitespace
and carriage returns.

I assume that's a joke. The point of minimising vertical whitespace
is to let the human reader see the whole structure of a function at
once.

And I'd be surprised if any modern compiler really generates better
code just because of the form of the initialisation.

-- Richard
 
P

pete

coder said:
What's wrong with the above line? I thought that the assignment
operator has right-left associativity.

It's somewhat controversial,
but it has been known to have problems with real compilers.
http://groups.google.com/group/comp.lang.c/search?hl=en&group=comp.lang.c&q="p+=+p+->+next+=+q"

Jack Klein explained it well.
http://groups.google.com/group/comp.lang.c/msg/5a955214830fbcd3

"you are assuming that precedence and associativity forces order of
operation again, and even more importantly that it forces order of
modification of objects."
 
C

CBFalconer

pete said:
It's somewhat controversial,
but it has been known to have problems with real compilers.
http://groups.google.com/group/comp.lang.c/search?hl=en&group=comp.lang.c&q="p+=+p+->+next+=+q"

Jack Klein explained it well.
http://groups.google.com/group/comp.lang.c/msg/5a955214830fbcd3

"you are assuming that precedence and associativity forces order of
operation again, and even more importantly that it forces order of
modification of objects."

If it doesn't work the compiler is badly broken. C expressions
have a value. Without side effects order of evaluation doesn't
enter into it.
 
D

Dave Hansen

... snip ...





If it doesn't work the compiler is badly broken. C expressions
have a value. Without side effects order of evaluation doesn't
enter into it.

Did you read the reference?

Given
p = p->next = q;
The compiler is free to compile this as if you had written
p = q;
p->next = q;
or
p->next = q;
p = q;

There is a difference. Quoting from the referenced article:

"I am not saying that any given compiler would actually execute
that
statement in that sequence, but THERE IS NOTHING IN THE C STANDARD
THAT PREVENTS IT."

If you want the latter semantics, write the latter syntax.

Regards,
-=Dave
 
C

CBFalconer

Dave said:
.... snip ...

Did you read the reference?

Given
p = p->next = q;
The compiler is free to compile this as if you had written
p = q;
p->next = q;
or
p->next = q;
p = q;

There is a difference. Quoting from the referenced article:

No, but I still disagree. The left assignment is of the value of
the statement "p->next = q". To evaluate that statement you have
to evaluate the assignment "= q". There never is an assignment "p
= q" in the chain. This is because, in C, assignment statements
have a value, and that statement has to be performed before that
value is available. The point is that the value is that of the
completed assignment statement.
 
O

Old Wolf

No reason not to. Same effect.

Hardly, the latter causes undefined behaviour. Without an
intervening sequence point, p is both written, and read for
a purpose other than to determine the value to be written.
(That purpose is in fact to determine the location to write
another value).

To put it another way:
(p->next = q)
evaluates to q and has side-effect of updating p->next with q.
So the parent expression has side-effect of updating p with q.

There's no sequence point, so either side-effect could occur
first. Since both side-effects involve 'p' and one of them is
a write, the behaviour is undefined.
 
B

Ben Pfaff

pete said:
If this is what you mean:
p -> next = q;
p = q;
don't write it this way:
p = p -> next = q;

There have been multiple long, fierce threads on comp.lang.c and
comp.std.c covering this very issue over the years. I've started
some of them myself. I don't think there was ever consensus on
whether this is defined or undefined.

I try to avoid this kind of thing when I remember, because of the
uncertainty, but it is so "obviously correct" that it is
difficult to remember all the time.
 

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

Similar Threads


Members online

Forum statistics

Threads
474,263
Messages
2,571,064
Members
48,769
Latest member
Clifft

Latest Threads

Top