Dharaskar's C questions ???

A

aarklon

Hi all,

I was going through the Book "The Hidden Treasure of C" by
Rajiv Dharaskar,First edition 1995, 2005 reprint,ISBN-81-7029-550-5
published in india by BPB publications

The following are my questions after going through the book

1)

#include<stdlib.h>
#include<stdio.h>
#include<time.h>

int
main (void)
{
register int i;
volatile int j;
auto int k;

time_t s1, s2, s3, e1, e2, e3;

s1 = clock ();
for (i = 1; i <= 32000; i++)
e1 = clock ();
printf ("\n The time in seconds for register variable is %g\n",
difftime (e1, s1) / CLOCKS_PER_SEC);



s2 = clock ();
for (j = 1; j <= 32000; j++);
e2 = clock ();
printf ("\n The time in seconds for volatile variable is %g\n",
difftime (e2, s2) / CLOCKS_PER_SEC);

s3 = clock ();
for (j = 1; j <= 32000; j++);
e3 = clock ();
printf ("\n The time in seconds for auto variable is %g\n",
difftime (e3, s3) / CLOCKS_PER_SEC);

puts ("");
return (EXIT_SUCCESS);
}

I got the o/p as
The time in seconds for register variable is 0.02

The time in seconds for volatile variable is 0.01

The time in seconds for auto variable is 0

does this mean that accessing register variables is a slow
operation...???

2) why printf("\n ~5 = %d",~5); is giving o/p as -6
(how is 5 treated as an unsigned quantity or signed quantity)

or by default how does the compiler treats numeric literals..??

3) why a global declaration such as register int i; is not
allowed.

4) consider the following program


int
main (void)
{
int i;

printf("%d",sizeof i );

puts ("");
return (EXIT_SUCCESS);
}

it is giving the expected o/p 4 but when i change the line
printf("%d",sizeof i ); to printf("%d",sizeof int );
it is giving compilation error. why is this so..??

5) why the following declaration
extern static int i is not possible in C.

6) how correct is the usage of continue statement
instead of break statement in a switch.
I have heard that continue statement should be used only
within loops.

7) why the statement void aa=78; is not possible in C..??

8) i have seen a statement like printf("%Fp",main);
what exactly is the purpose of this format specifier %Fp

9) In this book an explanation is given as follows:-

if you try to write 'double' or 'float' type of variables in
hexadecimal or octal format, the compiler does not generate
any error message, but results obtained will be incorrect.

To what extent this explanation is true...????
 
S

santosh

Hi all,

I was going through the Book "The Hidden Treasure of C" by
Rajiv Dharaskar,First edition 1995, 2005 reprint,ISBN-81-7029-550-5
published in india by BPB publications

The following are my questions after going through the book

1)

#include<stdlib.h>
#include<stdio.h>
#include<time.h>

int
main (void)
{
register int i;
volatile int j;
auto int k;

The auto storage class specifier is redundant here.
time_t s1, s2, s3, e1, e2, e3;

s1 = clock ();

The clock() function returns values of type clock_t, not time_t.
for (i = 1; i <= 32000; i++)
e1 = clock ();

Ridiculous nonsense.
printf ("\n The time in seconds for register variable is %g\n",
difftime (e1, s1) / CLOCKS_PER_SEC);

Same thing.
s2 = clock ();
for (j = 1; j <= 32000; j++);
e2 = clock ();
printf ("\n The time in seconds for volatile variable is %g\n",
difftime (e2, s2) / CLOCKS_PER_SEC);

s3 = clock ();
for (j = 1; j <= 32000; j++);
e3 = clock ();
printf ("\n The time in seconds for auto variable is %g\n",
difftime (e3, s3) / CLOCKS_PER_SEC);

Totally broken. clock() return values need to be stored in a clock_t
object and the second call to clock() in each case has to be outside
the for loop.
puts ("");
return (EXIT_SUCCESS);
}

I got the o/p as
The time in seconds for register variable is 0.02

The time in seconds for volatile variable is 0.01

The time in seconds for auto variable is 0

does this mean that accessing register variables is a slow
operation...???

No. The code is broken.

I suggest that you ignore the book and get a real one like The C
Programming Language.

<snip>
 
B

Ben Bacarisse

santosh said:
Ridiculous nonsense.


Same thing.


Totally broken. clock() return values need to be stored in a clock_t
object and the second call to clock() in each case has to be outside
the for loop.

Broken yes, but the clock call *is* outside the loop in these two cases
(not in the first). Go figure.
I suggest that you ignore the book and get a real one like The C
Programming Language.

Absolutely.
 
S

santosh

Ben Bacarisse said:
Broken yes, but the clock call *is* outside the loop in these two
cases
(not in the first). Go figure.

Ah yes! Perfect illustration of an unreadable construct.
 
A

aarklon

am:






The auto storage class specifier is redundant here.



The clock() function returns values of type clock_t, not time_t.


Ridiculous nonsense.


Same thing.



Totally broken. clock() return values need to be stored in a clock_t
object and the second call to clock() in each case has to be outside
the for loop.






No. The code is broken.

I suggest that you ignore the book and get a real one like The C
Programming Language.

<snip>

Okay i agree with you. but i think u are from india and you the
situation there. a lot of students and teachers are following these
sort of books,especially written by one man named kanetkar.

whatever kanetkar says in his C books are often taken the last word
even if it is wrong and a poor student will have to go through
all these and is being made to prepare for exams based on these sort
of erroneous texts.

this is the only reason i decided to go through these books
so as to find out erroneous/broken stuff so that i can tell my
peers which and what part of the book is wrong..
 
S

santosh

Okay i agree with you. but i think u are from india and you the
situation there. a lot of students and teachers are following these
sort of books,especially written by one man named kanetkar.

I have no idea how correct or wrong the book by "kanetkar" is. But the
code you've presented above is wrong. Also the whole purpose of the
program is frivolous. Beginning programmers shouldn't be worrying about
the relative efficiencies of different types. The volatile qualifier is
just not beginner stuff while the register qualifier is pretty much
useless these days. And the auto specifier is redundant.

The glaring error is in using time_t objects to hold values of type
clock_t.

Also the coding style, if indeed you've reproduced it faithfully, is
poor, particularly placing the null statement at the tail of the for
loop.
whatever kanetkar says in his C books are often taken the last word
even if it is wrong and a poor student will have to go through
all these and is being made to prepare for exams based on these sort
of erroneous texts.

_The C Programming Language_ by Kernighan & Ritchie (2nd Ed.) and _C: A
Reference Manual_ by Harbison & Steele are two excellent C texts.
this is the only reason i decided to go through these books
so as to find out erroneous/broken stuff so that i can tell my
peers which and what part of the book is wrong..

Better to spend time learning from highly regarded books than trying to
correct hopeless cases. Also avoid any C textbook from one "Schildt".
You can't go wrong in using a book on C written by it's creators.
 
K

Keith Thompson

I got the o/p as
The time in seconds for register variable is 0.02

The time in seconds for volatile variable is 0.01

The time in seconds for auto variable is 0

does this mean that accessing register variables is a slow
operation...???

Those values are most likely within the margin of error (even if the
measurements are being done correctly).
2) why printf("\n ~5 = %d",~5); is giving o/p as -6
(how is 5 treated as an unsigned quantity or signed quantity)

or by default how does the compiler treats numeric literals..??

``5'' is of type int. ``~5'' is also of type int. It's value depends
on how signed integers are represented; it happens to be -6 on your
system (and on any system that uses two's-complement -- i.e., almost all
of them). "%d" is the correct format for printing a signed int. There
are no unsigned values in the statement.

But applying bitwise operators to signed operands is rarely a sensible
thing to do.
3) why a global declaration such as register int i; is not
allowed.

Because the standard says so.

The original rationale, I suspect, is that tying up a CPU register
(often a very scarce resource) for the entire lifetime of a program is
undesirable. (On the other hand, declaring a register variable in
main() does the same thing.)

But in standard C, the "register" keyword doesn't necessarily mean that
the variable is stored in a CPU register.
4) consider the following program


int
main (void)
{
int i;

printf("%d",sizeof i );

puts ("");
return (EXIT_SUCCESS);
}

it is giving the expected o/p 4 but when i change the line
printf("%d",sizeof i ); to printf("%d",sizeof int );
it is giving compilation error. why is this so..??

Missing "#include <stdio.h>" and "#include <stdlib.h>". It won't even
compile without the latter.

sizeof yields a value of type size_t; "%d" is not the correct format.
The simplest solution is to convert to another type and use the format
for that type. (C99 provides a specific format for size_t, but it's not
universally implemented.)

So:
printf("%d", (int)sizeof i);
or
printf("%lu", (unsigned long)sizeof i);
or
printf("%zu", sizeof i); /* C99 only */

sizeof applied to an expression doesn't require parentheses (unless the
parentheses are required for other reasons). sizeof applied to a type
name does require parentheses.
5) why the following declaration
extern static int i is not possible in C.

Why should it be?
6) how correct is the usage of continue statement
instead of break statement in a switch.
I have heard that continue statement should be used only
within loops.

"continue" applies to the innermost enclosing loop; it doesn't apply to
switch statements.
7) why the statement void aa=78; is not possible in C..??

Why should it be? What would it mean?
8) i have seen a statement like printf("%Fp",main);
what exactly is the purpose of this format specifier %Fp

There is no such format specifier in standard C. Nor is there a
standard format specifier to print the value of a function pointer. I
suspect that "%Fp" is an implementation-defined extension to print a
function pointer (which is a good idea, and I wouldn't mind seeing it
added to the standard).
9) In this book an explanation is given as follows:-

if you try to write 'double' or 'float' type of variables in
hexadecimal or octal format, the compiler does not generate
any error message, but results obtained will be incorrect.

To what extent this explanation is true...????

If this is referring to printf formats, it's more or less valid, but the
point isn't about decimal vs. octal vs. hexadecimal. Each printf format
expects a specific type. Using a different type invokes undefined behavior.

But note that C99 adds the "%a" format, which prints floating-point
values in hexadecimal.
 
C

Christopher Benson-Manica

[comp.lang.c] Keith Thompson said:
3) why a global declaration such as register int i; is not
allowed.
The original rationale, I suspect, is that tying up a CPU register
(often a very scarce resource) for the entire lifetime of a program is
undesirable.

Given that it's an ignorable suggestion rather than a command, I would
think that there might be some other explanation for disallowing the
construct.
 
K

Keith Thompson

Keith said:
(e-mail address removed) wrote: [...]
3) why a global declaration such as register int i; is not
allowed.

Because the standard says so.

The original rationale, I suspect, is that tying up a CPU register
(often a very scarce resource) for the entire lifetime of a program is
undesirable. (On the other hand, declaring a register variable in
main() does the same thing.)

But in standard C, the "register" keyword doesn't necessarily mean that
the variable is stored in a CPU register.

In a followup that hasn't yet shown up on aioe.org,
| Given that it's an ignorable suggestion rather than a command, I would
| think that there might be some other explanation for disallowing the
| construct.

The "register" keyword existed long before C was formally standardized.
I suspect that when it was first implemented, it wasn't considered to
be merely a suggestion; rather, it probably *required* the compiler to
store the specified variable in a register. In that context, not
supporting "register" for static objects probably made sense.

In any case, "register" is treated as a special restricted version of
"auto". The language easily *could* have supported "register" for
static objects, but apparently it was thought that there's not much
point in doing so. The cost would be addition complication for the
compiler (assuming it's not just ignored); the benefit would be
insignificant.

Not every feature that can be provided should be provided.
 
J

J. J. Farrell

santosh said:
Ah yes! Perfect illustration of an unreadable construct.

Perfectly and easily readable, just has to be read carefully. Very
easily misread, and hence a style to be entirely avoided, certainly.
 
C

CBFalconer

Keith said:
.... snip ...

In any case, "register" is treated as a special restricted version
of "auto". The language easily *could* have supported "register"
for static objects, but apparently it was thought that there's not
much point in doing so. The cost would be addition complication
for the compiler (assuming it's not just ignored); the benefit
would be insignificant.

What you can count on is that the 'register' variable cannot have
its address taken.
 
A

aarklon

"continue" applies to the innermost enclosing loop; it doesn't apply to switch statements.

but i have seen a program like this:-

#include<stdio.h>

int main(void)
{
int i,cho;

for(i=1;i<=3;i++)
{
printf("%d. Enter your choice between 1 to 5:",i);
scanf("%d",&cho);

switch(cho)
{

case 1:
printf("case 1\n");
continue;

case 2:
printf("case 2\n");
break;

case 3:
printf("case 3\n");
continue;
}
}

return(EXIT_SUCCESS);
}

and the o/p is given as

1. Enter your choice between 1 to 5: 1
case 1
2.Enter your choice between 1 to 5: 2
case 2
3.Enter your choice between 1 to 5: 3
case 3
 
J

James Kuyper

but i have seen a program like this:-

#include<stdio.h>

int main(void)
{
int i,cho;

for(i=1;i<=3;i++)
{
printf("%d. Enter your choice between 1 to 5:",i);
scanf("%d",&cho);

switch(cho)
{

case 1:
printf("case 1\n");
continue;

case 2:
printf("case 2\n");
break;

case 3:
printf("case 3\n");
continue;
}

Those continue statements refer to the for loop, not the switch. An easy
way to demonstrate this is to insert the following code:

printf("Loop end\n");

The modified program will print "Loop end" only if cho is something
other than 1 or 3.
 
J

J. J. Farrell

but i have seen a program like this:-

#include<stdio.h>

int main(void)
{
int i,cho;

for(i=1;i<=3;i++)
{
printf("%d. Enter your choice between 1 to 5:",i);
scanf("%d",&cho);

switch(cho)
{

case 1:
printf("case 1\n");
continue;

case 2:
printf("case 2\n");
break;

case 3:
printf("case 3\n");
continue;
}
}

return(EXIT_SUCCESS);
}

and the o/p is given as

1. Enter your choice between 1 to 5: 1
case 1
2.Enter your choice between 1 to 5: 2
case 2
3.Enter your choice between 1 to 5: 3
case 3

Why do you say "but"? Think about Keith's explanation and how it applies
in this case. You'll see that in this particular case the effects of
'break' and 'continue' are identical.
 
C

Charlie Gordon

Keith Thompson said:
Keith said:
(e-mail address removed) wrote: [...]
3) why a global declaration such as register int i; is not
allowed.

Because the standard says so.

The original rationale, I suspect, is that tying up a CPU register (often
a very scarce resource) for the entire lifetime of a program is
undesirable. (On the other hand, declaring a register variable in main()
does the same thing.)

But in standard C, the "register" keyword doesn't necessarily mean that
the variable is stored in a CPU register.

In a followup that hasn't yet shown up on aioe.org,
| Given that it's an ignorable suggestion rather than a command, I would
| think that there might be some other explanation for disallowing the
| construct.

The "register" keyword existed long before C was formally standardized. I
suspect that when it was first implemented, it wasn't considered to be
merely a suggestion; rather, it probably *required* the compiler to store
the specified variable in a register. In that context, not supporting
"register" for static objects probably made sense.

In any case, "register" is treated as a special restricted version of
"auto". The language easily *could* have supported "register" for static
objects, but apparently it was thought that there's not much point in
doing so. The cost would be addition complication for the compiler
(assuming it's not just ignored); the benefit would be insignificant.

Not every feature that can be provided should be provided.

gcc supports global register variables as a processor specific extension.
I remember using one once for an interpreter core, to hold a pointer to the
interpreter state across function calls. It provided noticeable performance
improvements, but I would not advise beginners to mess with stuff like that,
especially with more modern processors, with more registers and more
parameters passed in registers.
 
D

David Thompson

register int i;
volatile int j;
auto int k;

time_t s1, s2, s3, e1, e2, e3;

s1 = clock ();
for (i = 1; i <= 32000; i++)
e1 = clock ();
printf ("\n The time in seconds for register variable is %g\n",
difftime (e1, s1) / CLOCKS_PER_SEC);
As already noted, this loop should have an empty body and the second
clock() call should follow it for consistency with the other cases;
and all the clock() values should be clock_t not time_t.

Also (and related) difftime() is used to difference two time() values
(as type time_t) which need not be linear. It is not needed and in
general not appropriate for differencing clock() values, which ARE
required to be linear (except for wraparound). However, on most
systems time_t is linear so difftime() is just subtraction and clock_t
does not have a greater range than time_t so this accidentally works.

But:
The time in seconds for register variable is 0.02

The time in seconds for volatile variable is 0.01

The time in seconds for auto variable is 0

does this mean that accessing register variables is a slow
operation...???
Your measurements are so close to the likely clock() granularity that
the signal, if any, is lost in the noise. Moreover, your trivial loops
easily could be optimized away, making this meaningless.

The basic answer, like most questions of performance in C, is that it
is not defined by the standard and depends on the implementation(s)
you are using, which in turn usually depend on the underlying machine.
Either do valid measurements -- which need to be repeated several
times, on systems (hardware and software) which are both controlled
and varied in known ways; or look at the compiled code (assuming your
implementation is indeed a compiler as essentially all are) together
with an understanding of the machine that will execute it and that
machine's performance for different instructions and memory accesses
-- which itself is often very complex and even nondeterministic on
many modern machines.

Or stop and think instead: if e.g. you spend days of your time, and
perhaps that of several colleages, to save one thousandth of a second
when the program runs, in order to 'break even' purely in time terms,
your program must be run a thousand times by a million users, or once
by a billion users -- and before Moore's Law reduces the amount of
saving to a negligible value, say within 5 years. Is that likely?

<snip other>
- formerly david.thompson1 || achar(64) || worldnet.att.net
 

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,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top