Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #41578 > unrolled thread
| Started by | SAHIL MAHLA <sahilmehla@gmail.com> |
|---|---|
| First post | 2014-03-10 14:50 -0700 |
| Last post | 2014-03-11 22:01 +0000 |
| Articles | 20 on this page of 42 — 17 participants |
Back to article view | Back to comp.lang.c
c prog -plz explain SAHIL MAHLA <sahilmehla@gmail.com> - 2014-03-10 14:50 -0700
Re: c prog -plz explain Keith Thompson <kst-u@mib.org> - 2014-03-10 15:41 -0700
Re: c prog -plz explain Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-03-10 23:21 +0000
Re: c prog -plz explain Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-03-10 23:24 +0000
Re: c prog -plz explain SAHIL MAHLA <sahilmehla@gmail.com> - 2014-03-10 20:28 -0700
Re: c prog -plz explain James Kuyper <jameskuyper@verizon.net> - 2014-03-11 00:15 -0400
Re: c prog -plz explain Kaz Kylheku <kaz@kylheku.com> - 2014-03-11 07:12 +0000
Re: c prog -plz explain Noob <root@127.0.0.1> - 2014-03-12 10:43 +0100
Re: c prog -plz explain Kaz Kylheku <kaz@kylheku.com> - 2014-03-12 14:38 +0000
Re: c prog -plz explain Noob <root@127.0.0.1> - 2014-03-12 15:56 +0100
Re: c prog -plz explain Eric Sosman <esosman@comcast-dot-net.invalid> - 2014-03-12 11:16 -0400
Re: c prog -plz explain James Kuyper <jameskuyper@verizon.net> - 2014-03-12 11:36 -0400
Re: c prog -plz explain Kaz Kylheku <kaz@kylheku.com> - 2014-03-12 15:38 +0000
Re: c prog -plz explain glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2014-03-12 19:13 +0000
Re: c prog -plz explain Eric Sosman <esosman@comcast-dot-net.invalid> - 2014-03-12 16:05 -0400
Re: c prog -plz explain James Kuyper <jameskuyper@verizon.net> - 2014-03-12 16:32 -0400
Re: c prog -plz explain Ian Collins <ian-news@hotmail.com> - 2014-03-13 09:38 +1300
Re: c prog -plz explain Tim Rentsch <txr@alumni.caltech.edu> - 2014-03-29 08:32 -0700
Re: c prog -plz explain glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2014-03-12 19:03 +0000
Re: c prog -plz explain James Kuyper <jameskuyper@verizon.net> - 2014-03-12 15:33 -0400
Re: c prog -plz explain Kaz Kylheku <kaz@kylheku.com> - 2014-03-12 20:56 +0000
Re: c prog -plz explain Ian Collins <ian-news@hotmail.com> - 2014-03-13 10:07 +1300
Re: c prog -plz explain "BartC" <bc@freeuk.com> - 2014-03-11 10:33 +0000
Re: c prog -plz explain Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2014-03-10 18:48 -0400
Re: c prog -plz explain SAHIL MAHLA <sahilmehla@gmail.com> - 2014-03-10 20:26 -0700
Re: c prog -plz explain Ian Collins <ian-news@hotmail.com> - 2014-03-11 16:34 +1300
typecasting (was Re: c prog -plz explain) Jorgen Grahn <grahn+nntp@snipabacken.se> - 2014-03-12 07:03 +0000
Re: typecasting (was Re: c prog -plz explain) Kaz Kylheku <kaz@kylheku.com> - 2014-03-12 07:40 +0000
Re: typecasting (was Re: c prog -plz explain) Lowell Gilbert <lgusenet@be-well.ilk.org> - 2014-03-12 10:47 -0400
Re: typecasting (was Re: c prog -plz explain) Ken Brody <kenbrody@spamcop.net> - 2014-03-12 13:01 -0400
Re: typecasting (was Re: c prog -plz explain) Richard <rgrdev_@gmail.com> - 2014-03-12 12:47 +0100
Re: typecasting (was Re: c prog -plz explain) gazelle@shell.xmission.com (Kenny McCormack) - 2014-03-12 12:39 +0000
Re: typecasting (was Re: c prog -plz explain) Kaz Kylheku <kaz@kylheku.com> - 2014-03-12 15:06 +0000
Re: c prog -plz explain Kaz Kylheku <kaz@kylheku.com> - 2014-03-11 07:26 +0000
Re: c prog -plz explain Richard <rgrdev_@gmail.com> - 2014-03-11 08:39 +0100
Re: c prog -plz explain Kaz Kylheku <kaz@kylheku.com> - 2014-03-11 08:08 +0000
Re: c prog -plz explain Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2014-03-11 09:14 -0400
Re: c prog -plz explain Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-03-11 15:38 +0000
Re: c prog -plz explain Ken Brody <kenbrody@spamcop.net> - 2014-03-11 12:53 -0400
Re: c prog -plz explain Keith Thompson <kst-u@mib.org> - 2014-03-11 11:47 -0700
Re: c prog -plz explain glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2014-03-11 21:41 +0000
Re: c prog -plz explain Kaz Kylheku <kaz@kylheku.com> - 2014-03-11 22:01 +0000
Page 1 of 3 [1] 2 3 Next page →
| From | SAHIL MAHLA <sahilmehla@gmail.com> |
|---|---|
| Date | 2014-03-10 14:50 -0700 |
| Subject | c prog -plz explain |
| Message-ID | <71fb68ed-69a6-42da-b988-520f9c400ff4@googlegroups.com> |
#include <stdio.h>
void incme(double *p)
{
*p += 1;
}
int main(void)
{
int i = 1;
double j=i;
incme((double*)&i);
printf("%d,%g",i,j);
return 0;
}
The output is :
0,1
I feel it should be :
2,1
Thanks in advance!!!
[toc] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2014-03-10 15:41 -0700 |
| Message-ID | <lnvbvlsmm0.fsf@nuthaus.mib.org> |
| In reply to | #41578 |
SAHIL MAHLA <sahilmehla@gmail.com> writes:
> #include <stdio.h>
> void incme(double *p)
> {
> *p += 1;
> }
>
> int main(void)
> {
> int i = 1;
> double j=i;
> incme((double*)&i);
> printf("%d,%g",i,j);
> return 0;
> }
>
> The output is :
>
> 0,1
>
> I feel it should be :
>
> 2,1
You posted this exact same program, with different output, in the other
thread. See Barry Schwarz's followup.
And please take the time to spell out words: "please" rather than "plz".
Silly abbreviations like that just make your text more difficult to
read.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2014-03-10 23:21 +0000 |
| Message-ID | <0.09075131e2de08b336cb.20140310232147GMT.87iorly704.fsf@bsb.me.uk> |
| In reply to | #41581 |
Keith Thompson <kst-u@mib.org> writes:
> SAHIL MAHLA <sahilmehla@gmail.com> writes:
>> #include <stdio.h>
>> void incme(double *p)
>> {
>> *p += 1;
>> }
>>
>> int main(void)
>> {
>> int i = 1;
>> double j=i;
>> incme((double*)&i);
>> printf("%d,%g",i,j);
>> return 0;
>> }
>>
>> The output is :
>>
>> 0,1
>>
>> I feel it should be :
>>
>> 2,1
>
> You posted this exact same program, with different output, in the other
> thread. See Barry Schwarz's followup.
This is a different program. This one is undefined because it converts
an 'int *' to a 'double *' and passes that to the incme function.
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2014-03-10 23:24 +0000 |
| Message-ID | <0.c3aabb76fba6cdaabd11.20140310232404GMT.87d2hty6wb.fsf@bsb.me.uk> |
| In reply to | #41583 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > Keith Thompson <kst-u@mib.org> writes: <snip> >> You posted this exact same program, with different output, in the other >> thread. See Barry Schwarz's followup. > > This is a different program. This one is undefined because it converts > an 'int *' to a 'double *' and passes that to the incme function. Ah, but this "different" program was also posted in the other thread! Sorry for the noise. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | SAHIL MAHLA <sahilmehla@gmail.com> |
|---|---|
| Date | 2014-03-10 20:28 -0700 |
| Message-ID | <fb286c5b-c72d-4615-b613-ac1c27f94107@googlegroups.com> |
| In reply to | #41583 |
On Tuesday, March 11, 2014 4:51:47 AM UTC+5:30, Ben Bacarisse wrote:
> Keith Thompson <kst-u@mib.org> writes:
>
>
>
> > SAHIL MAHLA <sahilmehla@gmail.com> writes:
>
> >> #include <stdio.h>
>
> >> void incme(double *p)
>
> >> {
>
> >> *p += 1;
>
> >> }
>
> >>
>
> >> int main(void)
>
> >> {
>
> >> int i = 1;
>
> >> double j=i;
>
> >> incme((double*)&i);
>
> >> printf("%d,%g",i,j);
>
> >> return 0;
>
> >> }
>
> >>
>
> >> The output is :
>
> >>
>
> >> 0,1
>
> >>
>
> >> I feel it should be :
>
> >>
>
> >> 2,1
>
> >
>
> > You posted this exact same program, with different output, in the other
>
> > thread. See Barry Schwarz's followup.
>
>
>
> This is a different program. This one is undefined because it converts
>
> an 'int *' to a 'double *' and passes that to the incme function.
>
>
>
> <snip>
>
> --
>
> Ben.
Hi Ben ,
Yes we are converting a int* to double*.Could you generalize this with a rule why that is undefined.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2014-03-11 00:15 -0400 |
| Message-ID | <lfm2ka$jgt$1@dont-email.me> |
| In reply to | #41589 |
On 03/10/2014 11:28 PM, SAHIL MAHLA wrote:
> On Tuesday, March 11, 2014 4:51:47 AM UTC+5:30, Ben Bacarisse wrote:
>> Keith Thompson <kst-u@mib.org> writes:
>>> SAHIL MAHLA <sahilmehla@gmail.com> writes:
>>>> #include <stdio.h>
>>>> void incme(double *p)
>>>> {
>>>> *p += 1;
>>>> }
>>>> int main(void)
>>>> {
>>>> int i = 1;
>>>> double j=i;
>>>> incme((double*)&i);
>>>> printf("%d,%g",i,j);
>>>> return 0;
>>>> }
>>>> The output is :
>>>> 0,1
>>>> I feel it should be :
>>>> 2,1
...
>> This is a different program. This one is undefined because it converts
>> an 'int *' to a 'double *' and passes that to the incme function.
>> <snip>
>> --
>> Ben.
>
> Hi Ben ,
> Yes we are converting a int* to double*.Could you generalize this with a rule why that is undefined.
A pointer to an object of one type can be converted to a pointer to an
object with a completely unrelated type. However, if the pointer is not
correctly aligned for the new type, the behavior of the conversion is
undefined. (6.3.2.3p7) That could apply here, but it's not the most
serious problem you face.
The really serious problem is that most objects have an effective type
(the only exception is dynamically allocated memory that has not yet
been accessed using a pointer to a non-character type). If you attempt
to access an object with one types, using an lvalue of a different type,
it is called type punning. The result of type punning is usually
undefined behavior. In this case, the effective type of 'i' is the same
as it's declared type, 'int'. The expression *p is an lvalue of type
double. Therefore, attempting to access the memory set aside to hold
'i', using the expression *p, has undefined behavior.
It is possible to use type punning safely. However, unless one of the
two types involved is a character type, they must be closely related
types, and 'int' is completely unrelated to 'double'. The precise rules
are given in 6.5p7, but until you've learned those rules, the safest
course is to avoid type punning.
The basic reason for this rule is simple. Any object in C is represented
by a series of bytes. For each object type, there is some precise rule
that connects the value of each byte, and the value represented by that
object, and it's generally a completely different rule for objects of
different types. Type punning takes bytes that represented one value
according to the rules for one type, and reinterprets them as if they
represented a value according to the rules of a different type. This
obviously can't work if the new type is larger than the original type,
but even if they are the same size, it can fail, in some cases
catastrophically. C's rules define the cases where you can portably rely
upon type punning to work in some useful fashion.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2014-03-11 07:12 +0000 |
| Message-ID | <20140310235955.176@kylheku.com> |
| In reply to | #41589 |
On 2014-03-11, SAHIL MAHLA <sahilmehla@gmail.com> wrote:
> Yes we are converting a int* to double*.Could you generalize this with a rule
> why that is undefined.
Yes. The rule is written in a document called ISO 9899 ("International
Standard -- Programming Languages -- C").
It was first published in 1990 (ISO 9899:1990) and describes a language called C90.
It was updated to ISO 9899:1999 (C99), and 2011 (C11).
If you read the standard, you will learn about all kinds of rules.
It's really too complicated (and more importantly inefficient) to lecture about
in a series of Usenet articles to complete newbies. Why don't you read the document,
and then if you have questions, then it makes for a better discussion
than "spoon feed me the rules", know what I mean?
The rule which applies here is that an object shall not be accessed through an
lvalue which is not its declared type (or a const/volatile qualified version of
its declared type). An object of type int being accessed as if it were an object
of type double results in undefined behavior.
C is a strongly typed language. It has the concept of type: that an operation
of the correct type must be applied to a datum for well-defined behavior. C has
considerable translation-time type checking in it to support its type system,
but when you use casts, especially for conversions among pointer types, you can
defeat the type system and write programs which break the rules, but do not
produce any diagnostics when compiled, and even make an executable.
[toc] | [prev] | [next] | [standalone]
| From | Noob <root@127.0.0.1> |
|---|---|
| Date | 2014-03-12 10:43 +0100 |
| Message-ID | <lfpa7b$150$1@dont-email.me> |
| In reply to | #41597 |
Kaz Kylheku wrote: > C is a strongly typed language. It has the concept of type: that an operation > of the correct type must be applied to a datum for well-defined behavior. C has > considerable translation-time type checking in it to support its type system, > but when you use casts, especially for conversions among pointer types, you can > defeat the type system and write programs which break the rules, but do not > produce any diagnostics when compiled, and even make an executable. Ergo, a simple rule for beginners would be: "Don't use casts anywhere". There are very few valid reasons for using casts. One is passing NULL to a variadic function (e.g. execl) Another is trying to define APIs with generic parameters (e.g. connect) i.e. the poor man's polymorphism. Regards.
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2014-03-12 14:38 +0000 |
| Message-ID | <20140312073525.267@kylheku.com> |
| In reply to | #41638 |
On 2014-03-12, Noob <root@127.0.0.1> wrote: > Kaz Kylheku wrote: > >> C is a strongly typed language. It has the concept of type: that an operation >> of the correct type must be applied to a datum for well-defined behavior. C has >> considerable translation-time type checking in it to support its type system, >> but when you use casts, especially for conversions among pointer types, you can >> defeat the type system and write programs which break the rules, but do not >> produce any diagnostics when compiled, and even make an executable. > > Ergo, a simple rule for beginners would be: "Don't use casts anywhere". > There are very few valid reasons for using casts. > > One is passing NULL to a variadic function (e.g. execl) > > Another is trying to define APIs with generic parameters (e.g. connect) > i.e. the poor man's polymorphism. What if you're calculating i / j, where i and j are integers, and you want an answer like 2.75? No i / (double) j for you; stick with two? :) The stupid thing is that completely bat-shit unsafe stuff shares the same notation with necessary conversions.
[toc] | [prev] | [next] | [standalone]
| From | Noob <root@127.0.0.1> |
|---|---|
| Date | 2014-03-12 15:56 +0100 |
| Message-ID | <lfpsig$4ic$2@dont-email.me> |
| In reply to | #41649 |
Kaz Kylheku wrote: > On 2014-03-12, Noob <root@127.0.0.1> wrote: >> Kaz Kylheku wrote: >> >>> C is a strongly typed language. It has the concept of type: that an operation >>> of the correct type must be applied to a datum for well-defined behavior. C has >>> considerable translation-time type checking in it to support its type system, >>> but when you use casts, especially for conversions among pointer types, you can >>> defeat the type system and write programs which break the rules, but do not >>> produce any diagnostics when compiled, and even make an executable. >> >> Ergo, a simple rule for beginners would be: "Don't use casts anywhere". > >> There are very few valid reasons for using casts. I realize now that I only considered "pointer" casts. >> One is passing NULL to a variadic function (e.g. execl) >> >> Another is trying to define APIs with generic parameters (e.g. connect) >> i.e. the poor man's polymorphism. > > What if you're calculating i / j, where i and j are integers, and you > want an answer like 2.75? > > No i / (double) j for you; stick with two? :) Doh! One trying to abide by the aforementioned "simple rule" could rely on implicit conversion, as in double d_i = i, d_j = j, res = d_i / d_j; But I do see your point. Perhaps the rule should be "Don't use pointer casts anywhere" > The stupid thing is that completely bat-shit unsafe stuff shares the same > notation with necessary conversions. Do you have other examples of reasonable use of casts? Regards.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2014-03-12 11:16 -0400 |
| Message-ID | <lfptob$eeu$1@dont-email.me> |
| In reply to | #41651 |
On 3/12/2014 10:56 AM, Noob wrote:
> Kaz Kylheku wrote:
>> On 2014-03-12, Noob <root@127.0.0.1> wrote:
>>> [...]
>>> Ergo, a simple rule for beginners would be: "Don't use casts anywhere".
>>
>>> There are very few valid reasons for using casts.
>
> I realize now that I only considered "pointer" casts.
>[...]
> Perhaps the rule should be "Don't use pointer casts anywhere"
> [...]
> Do you have other examples of reasonable use of casts?
How about converting between a struct pointer and a pointer
to the struct's first element? Or using a struct pointer and
a byte offset to get to an element of the struct? (Both of these
might be considered beyond the "beginner" boundary.)
How about implementing a comparator function for qsort() or
bsearch()? Personally, I prefer to introduce a couple helper
variables:
int compare(const void *pp, const void *qq) {
const struct whatnot *p = pp, *q = qq;
return strcmp(p->name, q->name);
}
... but doing without the extra variables and applying casts
to the arguments would be perfectly reasonable.
Since there's no analog to `void*' for function pointers,
casts are often necessary when dealing with pointers to functions
of dissimilar types. (Beyond beginner boundary?)
--
Eric Sosman
esosman@comcast-dot-net.invalid
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2014-03-12 11:36 -0400 |
| Message-ID | <lfput3$n8p$1@dont-email.me> |
| In reply to | #41653 |
On 03/12/2014 11:16 AM, Eric Sosman wrote:
> On 3/12/2014 10:56 AM, Noob wrote:
...
>> I realize now that I only considered "pointer" casts.
>> [...]
>> Perhaps the rule should be "Don't use pointer casts anywhere"
>> [...]
>> Do you have other examples of reasonable use of casts?
>
> How about converting between a struct pointer and a pointer
> to the struct's first element?
In one direction, there's a perfectly safe alternative:
&struct_pointer->first_member (unless the struct has an opaque type -
but it really shouldn't have an opaque type in any code that is going to
try to access it's members). It's only going in the other direction that
requires a cast.
> How about implementing a comparator function for qsort() or
> bsearch()? Personally, I prefer to introduce a couple helper
> variables:
>
> int compare(const void *pp, const void *qq) {
> const struct whatnot *p = pp, *q = qq;
> return strcmp(p->name, q->name);
> }
>
> ... but doing without the extra variables and applying casts
> to the arguments would be perfectly reasonable.
Because I prefer to treat casts as danger signs, I also prefer using the
the helper variables.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2014-03-12 15:38 +0000 |
| Message-ID | <20140312083622.959@kylheku.com> |
| In reply to | #41651 |
On 2014-03-12, Noob <root@127.0.0.1> wrote: > Do you have other examples of reasonable use of casts? (out_of_the_fucking_newsgroup) useless_pedant; I will let you know if I think of anything else.
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2014-03-12 19:13 +0000 |
| Message-ID | <lfqbl5$it2$1@speranza.aioe.org> |
| In reply to | #41649 |
Kaz Kylheku <kaz@kylheku.com> wrote: > On 2014-03-12, Noob <root@127.0.0.1> wrote: (snip) >> Ergo, a simple rule for beginners would be: "Don't use casts anywhere". (snip) > What if you're calculating i / j, where i and j are integers, and you > want an answer like 2.75? > No i / (double) j for you; stick with two? :) > The stupid thing is that completely bat-shit unsafe stuff shares > the same notation with necessary conversions. Well, first, I agree, but sometimes there are ways around it. If you want percentage, you can: pct=100.*i/j; no cast needed, because the multiply will force the conversion. Also, sometimes in the case where I want i/j not to be integer, it turns out to make more sense for i and/or j to be double. Also, often when I have i and j, I don't want i/j to be integer but i*(large_integer)/j to be integer. Conveniently, most processors allow for this. Inconveniently, C doesn't. -- glen
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2014-03-12 16:05 -0400 |
| Message-ID | <lfqeli$qls$1@dont-email.me> |
| In reply to | #41678 |
On 3/12/2014 3:13 PM, glen herrmannsfeldt wrote:
> Kaz Kylheku <kaz@kylheku.com> wrote:
>> On 2014-03-12, Noob <root@127.0.0.1> wrote:
>
> (snip)
>>> Ergo, a simple rule for beginners would be: "Don't use casts anywhere".
>
> (snip)
>
>> What if you're calculating i / j, where i and j are integers, and you
>> want an answer like 2.75?
>
>> No i / (double) j for you; stick with two? :)
>
>> The stupid thing is that completely bat-shit unsafe stuff shares
>> the same notation with necessary conversions.
>
> Well, first, I agree, but sometimes there are ways around it.
>
> If you want percentage, you can:
>
> pct=100.*i/j;
>
> no cast needed, because the multiply will force the conversion.
ObPuzzle: Which of the `return' statements below is the best,
and why?
#include <time.h>
/**
* Find how many CPU seconds were consumed between
* two values returned by clock().
*/
double cpuSeconds(clock_t t0, clock_t t1) {
/* A */ return (t1 - t0) / CLOCKS_PER_SEC;
/* B */ return (t1 - t0) / (double) CLOCKS_PER_SEC;
/* C */ return (t1 - t0) / (CLOCKS_PER_SEC + 0.0);
}
--
Eric Sosman
esosman@comcast-dot-net.invalid
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2014-03-12 16:32 -0400 |
| Message-ID | <lfqg89$8bi$1@dont-email.me> |
| In reply to | #41681 |
On 03/12/2014 04:05 PM, Eric Sosman wrote:
...
> ObPuzzle: Which of the `return' statements below is the best,
> and why?
>
> #include <time.h>
> /**
> * Find how many CPU seconds were consumed between
> * two values returned by clock().
> */
> double cpuSeconds(clock_t t0, clock_t t1) {
> /* A */ return (t1 - t0) / CLOCKS_PER_SEC;
> /* B */ return (t1 - t0) / (double) CLOCKS_PER_SEC;
> /* C */ return (t1 - t0) / (CLOCKS_PER_SEC + 0.0);
> }
Option A can't return fractions of a second if clock_t is an integer
type, so I wouldn't choose that. Also, it rounds fractional parts toward
0, whereas I prefer rounding to negative infinity.
If clock_t is long double, option B unnecessarily discards precision in
CLOCKS_PER_SEC, whereas option C unnecessarily discards precision in the
final result. I think that carrying out the actual calculation in long
double is slightly preferable, which favors C over B, but it's not a
strong preference.
I'd define cpuSeconds as returning long double, which would imply a
corresponding re-write of option B. With that re-write, I'd favor B as
the clearest of the two versions that deals correctly with the
possibility that clock_t is an integer type.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2014-03-13 09:38 +1300 |
| Message-ID | <bobuuuFbpi1U5@mid.individual.net> |
| In reply to | #41681 |
Eric Sosman wrote:
> On 3/12/2014 3:13 PM, glen herrmannsfeldt wrote:
>> Kaz Kylheku <kaz@kylheku.com> wrote:
>>> On 2014-03-12, Noob <root@127.0.0.1> wrote:
>>
>> (snip)
>>>> Ergo, a simple rule for beginners would be: "Don't use casts anywhere".
>>
>> (snip)
>>
>>> What if you're calculating i / j, where i and j are integers, and you
>>> want an answer like 2.75?
>>
>>> No i / (double) j for you; stick with two? :)
>>
>>> The stupid thing is that completely bat-shit unsafe stuff shares
>>> the same notation with necessary conversions.
>>
>> Well, first, I agree, but sometimes there are ways around it.
>>
>> If you want percentage, you can:
>>
>> pct=100.*i/j;
>>
>> no cast needed, because the multiply will force the conversion.
>
> ObPuzzle: Which of the `return' statements below is the best,
> and why?
>
> #include <time.h>
> /**
> * Find how many CPU seconds were consumed between
> * two values returned by clock().
> */
> double cpuSeconds(clock_t t0, clock_t t1) {
> /* A */ return (t1 - t0) / CLOCKS_PER_SEC;
> /* B */ return (t1 - t0) / (double) CLOCKS_PER_SEC;
> /* C */ return (t1 - t0) / (CLOCKS_PER_SEC + 0.0);
> }
>
Or Option D
double cpuSeconds(clock_t t0, clock_t t1) {
static const double clocksPerSec = CLOCKS_PER_SEC;
return (t1 - t0) / clocksPerSec;
}
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2014-03-29 08:32 -0700 |
| Message-ID | <kfnha6hkokh.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #41681 |
Eric Sosman <esosman@comcast-dot-net.invalid> writes:
> On 3/12/2014 3:13 PM, glen herrmannsfeldt wrote:
>> If you want percentage, you can:
>>
>> pct=100.*i/j;
>>
>> no cast needed, because the multiply will force the conversion.
>
> ObPuzzle: Which of the `return' statements below is the best,
> and why?
>
> #include <time.h>
> /**
> * Find how many CPU seconds were consumed between
> * two values returned by clock().
> */
> double cpuSeconds(clock_t t0, clock_t t1) {
> /* A */ return (t1 - t0) / CLOCKS_PER_SEC;
> /* B */ return (t1 - t0) / (double) CLOCKS_PER_SEC;
> /* C */ return (t1 - t0) / (CLOCKS_PER_SEC + 0.0);
> }
I offer without further comment a fourth alternative:
return (0 ? cpuSeconds(t0,t1) : t1-t0) / CLOCKS_PER_SEC;
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2014-03-12 19:03 +0000 |
| Message-ID | <lfqb14$h8h$1@speranza.aioe.org> |
| In reply to | #41638 |
Noob <root@127.0.0.1> wrote: > Kaz Kylheku wrote: >> C is a strongly typed language. It has the concept of type: >> that an operation of the correct type must be applied to a >> datum for well-defined behavior. C has considerable >> translation-time type checking in it to support its type system, >> but when you use casts, especially for conversions among >> pointer types, you can defeat the type system and write >> programs which break the rules, but do not produce any >> diagnostics when compiled, and even make an executable. > Ergo, a simple rule for beginners would be: "Don't use casts anywhere". There are enough uses for non-pointer casts that I wouldn't rule them out for beginners, but no good reasons that I can think of for pointer casts. -- glen
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2014-03-12 15:33 -0400 |
| Message-ID | <lfqcr0$bao$1@dont-email.me> |
| In reply to | #41676 |
On 03/12/2014 03:03 PM, glen herrmannsfeldt wrote:
...
> There are enough uses for non-pointer casts that I wouldn't rule
> them out for beginners, but no good reasons that I can think of
> for pointer casts.
So, would you write code like the following, to avoid casts?
double x;
void *temp = &x;
printf("%p\n", temp);
Imagine that a third party library declares
int third_party_func(char*);
even though third_party_func() doesn't write through the char* pointer,
it only reads from it. You don't have the influence needed to convince
them to use "const char*" instead. Your own code has:
const char *message = "This memory cannot be safely modified";
How do you pass message to third_party_func()?
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
Page 1 of 3 [1] 2 3 Next page →
Back to top | Article view | comp.lang.c
csiph-web