Endless loop question

T

Tweaxor

This has been puzzling me all this week. This is actually a homework
assignment
from last semesmter. But the teacher wouldn't tell us why certain
things didn't work, but it didn't just work. My thing was what
actually turn this while loop into an endless loop instead of waiting
for user response it'll would skip right over it. Could someone with
the time explain this to me what would make it behave like this


int pts1, pts2, pts3, wk_exp, p_pay, total_pts, total_pay;
char degree, again;

int main() {
char again = 'Y';

while (again != 'N')
{

printf("\nEnter degree type: (B for Bachelors), (M for Masters), (D
for Doctorate\n");
printf("\t\t\t: ");
scanf("%1c", &degree);
if (degree = 'B') {
pts1 = 3;
}
if (degree = 'M') {
pts1 = 5;
}
if (degree = 'D') {
pts1 =7;
}


printf("\nEnter number of years of work experience: ");
scanf("%2d",&wk_exp);
if (wk_exp <= 3) {
pts2 = 4;
}
if (wk_exp >= 4 && wk_exp <= 6) {
pts2 = 7;
}
if (wk_exp >= 7) {
pts2 = 10;
}

printf("\nEnter current Pay: ");
scanf("%5d",&p_pay);
if (p_pay <= 15000) {
pts3 = 4;
}
if (p_pay >= 15001 && p_pay <= 22500) {
pts3 = 8;
}
if (p_pay > 22500) {
pts3 = 12;
}

total_pts = pts1 + pts2 + pts3;
if (total_pts <= 19) {
total_pay = 25000;
}
if (total_pts >= 20 && total_pts <= 28) {
total_pay = 30000;
}
else if (total_pts >= 29) {
total_pay = 35000;
}

printf("\nThe pay rate is: %d\n",total_pay);

printf("\nWant to do this again? Press N for NO: ");
/*scanf("%1c", &again); */
getchar();
}

return (0) ;
}
 
M

Mark A. Odell

(e-mail address removed) (Tweaxor) wrote in

This has been puzzling me all this week. This is actually a homework
assignment
from last semesmter. But the teacher wouldn't tell us why certain
things didn't work, but it didn't just work. My thing was what
actually turn this while loop into an endless loop instead of waiting
for user response it'll would skip right over it. Could someone with
the time explain this to me what would make it behave like this

None of these seem to need to be defined outside of main().
int pts1, pts2, pts3, wk_exp, p_pay, total_pts, total_pay;
char degree, again;

int main() {
Ick ^^^^^^^^

int main(void)
{
char again = 'Y';

while (again != 'N')
{
/*scanf("%1c", &again); */
getchar();
}

return (0) ;

}

Since again is initially == 'Y', explain how again will ever be anything
but 'Y'. Then see why the while loop becomes endless.
 
A

Alan Balmer

No, why? You can drop `void' in function definition, can't you?

They mean different things. '(void)' tells the compiler there are no
arguments. '()' tells the compiler that the arguments are unspecified.
 
D

Dave Vandervies

They mean different things. '(void)' tells the compiler there are no
arguments. '()' tells the compiler that the arguments are unspecified.

In this case, though, the distinction doesn't make any difference; one
form means "Here's the definition of a function called main, returning
int and taking no arguments, without a prototype" and the other form
means "Here's the definition of a function called main, returning int
and taking no arguments, with a prototype".

Unless, of course, you're planning on calling main later on with a
nonempty argument list. But if you really want to lie to the compiler,
a prototype won't stop you either.


dave
((int (*)())main)(argv,argc);
 
S

S.Tobias

They mean different things. '(void)' tells the compiler there are no
arguments. '()' tells the compiler that the arguments are unspecified.

In declarations that are not definitions.

What can be unspecified in function definition?
int f() {}

Grep through n869.txt - there are two examples using "int main()"
(and one "int main(void)") declaration. They wouldn't miss an error
like that, would they?
 
F

Flash Gordon

On Wed, 29 Sep 2004 18:30:11 +0000 (UTC)
In this case, though, the distinction doesn't make any difference; one
form means "Here's the definition of a function called main, returning
int and taking no arguments, without a prototype" and the other form
means "Here's the definition of a function called main, returning int
and taking no arguments, with a prototype".

So why not give the compiler all the information you have? It's
generally a good habit and if you[1] break it for main you are likely to
break it for other functions.
Unless, of course, you're planning on calling main later on with a
nonempty argument list. But if you really want to lie to the
compiler, a prototype won't stop you either.

Actually, if there is a prototype in scope and you pass an incorrect
number of parameters the compiler is (I believe) *required* to produce a
diagnostic.

[1] The generic you, not the specific you.
 
1

187

Alan said:
They mean different things. '(void)' tells the compiler there are no
arguments. '()' tells the compiler that the arguments are unspecified.

but when it coems down to it, I've never seen any difference in actual
behavior between the two. When it comes to normal functions, there is no
difference.
 
D

Dave Vandervies

In this case, though, the distinction doesn't make any difference; one
form means "Here's the definition of a function called main, returning
int and taking no arguments, without a prototype" and the other form
means "Here's the definition of a function called main, returning int
and taking no arguments, with a prototype".

So why not give the compiler all the information you have? It's
generally a good habit and if you[1] break it for main you are likely to
break it for other functions.

Since main is already special in other ways, and since it's quite rare
for a programmer to write code that calls it, I don't see this as being
worth even an "Ick", only a "It's generally considered good form to
write this as..." (if even that).

(I would be entirely unsurprised to find that a large proportion, perhaps
even a majority, of programmers think of "int main()" (or "main()") as
"Define the entry point of this program" rather than "Define a function
called main [which happens to be the entry point of this program]",
so not writing a full prototype definition for main doesn't necessarily
indicate sloppiness that would carry over to writing other functions.)

Actually, if there is a prototype in scope and you pass an incorrect
number of parameters the compiler is (I believe) *required* to produce a
diagnostic.

....if you call it through the function name given in the prototype and
not, say, cast it to a nonprototyped function pointer type and call
through that.

Like I said, if you really want to lie to the compiler, a prototype
won't stop you.


dave
 
A

Alan Balmer

In declarations that are not definitions.

What can be unspecified in function definition?
int f() {}

Grep through n869.txt - there are two examples using "int main()"
(and one "int main(void)") declaration. They wouldn't miss an error
like that, would they?

The examples are not the standard. Your copy of the draft probably
includes section 5.1.2.2.1, paragraph 1, which gives the two allowable
forms, plus allows other *implementation-defined* forms. If the OP's
implementation documents that usage, it's OK. It probably doesn't.
 
A

Alan Balmer

but when it coems down to it, I've never seen any difference in actual
behavior between the two. When it comes to normal functions, there is no
difference.
If your compiler is paying attention, you should see a difference. If
you use "void", the compiler should complain when you invoke the
function with a parameter.
 
F

Flash Gordon

On Wed, 29 Sep 2004 20:22:20 +0000 (UTC)

<snip int main() vs int main(void)
So why not give the compiler all the information you have? It's
generally a good habit and if you[1] break it for main you are likely
to break it for other functions.

Since main is already special in other ways, and since it's quite rare
for a programmer to write code that calls it, I don't see this as
being worth even an "Ick", only a "It's generally considered good form
to write this as..." (if even that).

(I would be entirely unsurprised to find that a large proportion,
perhaps even a majority, of programmers think of "int main()" (or
"main()") as"Define the entry point of this program" rather than
"Define a function called main [which happens to be the entry point of
this program]",

I agree so far.
so not writing a full prototype definition for main
doesn't necessarily indicate sloppiness that would carry over to
writing other functions.)

Unfortunately it seems like a lot of programmers think of () as the
parameter list for no parameters.
...if you call it through the function name given in the prototype and
not, say, cast it to a nonprototyped function pointer type and call
through that.

Precisely. It means you have to work to do it, whereas not specifying
the parameter list makes calling a function (even main) with incorrect
parameters all too easy.
Like I said, if you really want to lie to the compiler, a prototype
won't stop you.

In that case I suggest you disable all warnings possibly on your
compiler since you can always find a way of achieving the same effect
without invoking the warnings.

In the mean time I will try to make the compiler warn me about all the
problems it can be made to detect (which don't generate spurious
warnings) since it generally improves code quality.
 
S

S.Tobias

Alan Balmer said:
In declarations that are not definitions.

What can be unspecified in function definition?
int f() {}

Grep through n869.txt - there are two examples using "int main()"
(and one "int main(void)") declaration. They wouldn't miss an error
like that, would they?
[/QUOTE]
The examples are not the standard. Your copy of the draft probably

True. If that's so then faq is also guilty, and K&R2 is
the greatest offender.
includes section 5.1.2.2.1, paragraph 1, which gives the two allowable
forms, plus allows other *implementation-defined* forms.

.... or equivalent, you forgot to add.
implementation documents that usage, it's OK. It probably doesn't.

6.7.5.3

10 The special case of an unnamed parameter of type void as the only
item in the list specifies that the function has no parameters.

14 [...] An empty list in a function declarator that is part of a
definition of that function specifies that the function has no
parameters. The empty list in a function declarator that is not part
of a definition of that function specifies that no information about
the number or types of the parameters is supplied.

If
void f() {}
and
void f(void) {}
are not equivalent, then my brain must be seriously in trouble.
 
A

Alan Balmer

The examples are not the standard. Your copy of the draft probably

True. If that's so then faq is also guilty, and K&R2 is
the greatest offender.
includes section 5.1.2.2.1, paragraph 1, which gives the two allowable
forms, plus allows other *implementation-defined* forms.

... or equivalent, you forgot to add.
implementation documents that usage, it's OK. It probably doesn't.

6.7.5.3

10 The special case of an unnamed parameter of type void as the only
item in the list specifies that the function has no parameters.

14 [...] An empty list in a function declarator that is part of a
definition of that function specifies that the function has no
parameters. The empty list in a function declarator that is not part
of a definition of that function specifies that no information about
the number or types of the parameters is supplied.

If
void f() {}
and
void f(void) {}
are not equivalent, then my brain must be seriously in trouble.

First, this has nothing to do with the standard's specification of the
"main" function. Second, read again what you quoted above, carefully.
It tells you what the difference is and where it applies.

Bottom line: if you have a function which takes no parameters, it is
never wrong to use "void" in its declarator. If you do, the compiler
will check for proper usage. It really takes little extra effort, and
is not worth discussing further.
 
S

S.Tobias

Alan Balmer said:
includes section 5.1.2.2.1, paragraph 1, which gives the two allowable
forms, plus allows other *implementation-defined* forms.

... or equivalent, you forgot to add. ^^^^^^^^^^^^^
6.7.5.3 [snip]

void f() {}
void f(void) {}
....are equivalent. If not, then why?
First, this has nothing to do with the standard's specification of the
"main" function.

I don't understand you. Of course the quotes didn't directly concern
main() definition. They only determined that the above function
definitions (one with, and one without prototype) were equivalent,
because they specified exactly same thing: no parameters.

5.1.2.2.1 mentions that main() definition may have equivalent form.
Therefore
int main() {...}
is as good as
int main(void) {...}

I don't see why one could not connect those two facts.
Bottom line: if you have a function which takes no parameters, it is
never wrong to use "void" in its declarator.

But I have never said it's wrong. All I have said is that you can
drop `void' from main() (or any other function) *definition*.
If you do, the compiler
will check for proper usage. It really takes little extra effort, and
is not worth discussing further.

Well, it's definitely not a problem for the compiler. But you have
seeded doubt in my mind, and I ask you to convince me I was wrong.
 
O

Old Wolf

S.Tobias said:
5.1.2.2.1 mentions that main() definition may have equivalent form.
Therefore
int main() {...}
is as good as
int main(void) {...}

They are not equivalent (as I will demonstrate below)
But I have never said it's wrong. All I have said is that you can
drop `void' from main() (or any other function) *definition*.


Well, it's definitely not a problem for the compiler. But you have
seeded doubt in my mind, and I ask you to convince me I was wrong.

int main()
{
return 0;
}

void foo()
{
main("muahaha!");
foo(1);
foo(2,3);
}

This compiles without error (and gives undefined behaviour
at runtime). It would give a compile error if you added 'void'
to the definition of main or foo.
 
M

Method Man

Since main is already special in other ways, and since it's quite rare
for a programmer to write code that calls it, I don't see this as being
worth even an "Ick", only a "It's generally considered good form to
write this as..."
Agreed.

(if even that).

It's worth mentioning so that a beginner can start writing code with proper
style eventhough he may not understand all the reasons for it at first.
 
J

j0mbolar

S.Tobias said:
Alan Balmer said:
includes section 5.1.2.2.1, paragraph 1, which gives the two allowable
forms, plus allows other *implementation-defined* forms.

... or equivalent, you forgot to add. ^^^^^^^^^^^^^
6.7.5.3 [snip]

void f() {}
void f(void) {}
...are equivalent. If not, then why?
First, this has nothing to do with the standard's specification of the
"main" function.

I don't understand you. Of course the quotes didn't directly concern
main() definition. They only determined that the above function
definitions (one with, and one without prototype) were equivalent,
because they specified exactly same thing: no parameters.

5.1.2.2.1 mentions that main() definition may have equivalent form.
Therefore
int main() {...}
is as good as
int main(void) {...}

I don't see why one could not connect those two facts.
Bottom line: if you have a function which takes no parameters, it is
never wrong to use "void" in its declarator.

But I have never said it's wrong. All I have said is that you can
drop `void' from main() (or any other function) *definition*.
If you do, the compiler
will check for proper usage. It really takes little extra effort, and
is not worth discussing further.

Well, it's definitely not a problem for the compiler. But you have
seeded doubt in my mind, and I ask you to convince me I was wrong.

Well, according to 6.7.5.3#14, I think it makes it
pretty clear that int main() semantically acts the same
as int main(void) but as though there was an explicit void.

As such, the compiler should realize that
int main() accepts no arguments and therefore
whenever used recursively(with arguments),
should produce some error.

However, 6.11.6 considers this usage to be
obsolescent so probably best avoided but
in actuality will more than likely
remain in the language.



Is this analysis correct?
 
S

S.Tobias

They are not equivalent (as I will demonstrate below)
[snip]

Thank you!

They are equivalent as to what they define, but not what they declare
(different types and consequences). Put together: not equivalent.

void f() { f(1); } // UB
void f(void) { f(1); } // diagnostics

OTOH, if the Standard makes so much effort to handle functions
without prototype (I gather this is for pre-ANSI compilers, that
didn't have them back then), I can't imagine why it should make
specifically non-prototype main() definition undefined.

I think I'm going to ask it in c.s.c.
 

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
473,755
Messages
2,569,536
Members
45,008
Latest member
HaroldDark

Latest Threads

Top