Calloc's zero initializing [was Re: 5 tap IIR Filter Impl]
Author |
Message |
u.. #1 / 22
|
 Calloc's zero initializing [was Re: 5 tap IIR Filter Impl]
On comp.dsp I posted the following:
> Also, you could use calloc() >instead of malloc() and skip the initialization step (calloc sets the >array to zero). "Since calloc'z zero fill is all bits zeros, it is guaranteed to yield the value 0 for all integral types (including '\0' for character types). But it does NOT guarantee usefull null pointer values (see Chapter 5) or floating-point zero values." (C Programming FAQs by Steve Summit). Since the x and y are pointers to type double, relying on calloc for zero initial values will not result in portable code. Klaus Bahner responded with this: Isn't this statement a bit too theoretical? In theory, this is correct, since C doesn't define the exact implementation of float types. So, once your system represents a floating point zero by a non-zero bit pattern, the statement is correct. BUT: A (positive) zero according to the IEEE floating point standard is always defined as all bits set to zero. This yields for all types (single, double and extended). Hence on all FPUs which obey to the IEEE standard calloc actually guarantuess useful (namely +0.0) zero values for all float data types. And I don't know of any FPU not following the standard so far. There are of course non-IEEE compatible modes (SHARC, PowerPC for instance), but the incompatibility addresses only the handling of denormalized numbers and rounding modes - not the definition of zeroes. So I think, you will have a hard time in order to find a system where float *x; x = (float *) calloc ( LENGTH * sizeof(float)); /* initializes *x to +0.0 */ is non portable code. In my opinion the same yields for NULL pointers. I've never seen any C compiler defining NULL different than "#define NULL (void *) 0x0", whereby NULL is mapped to an integral type. Can the folks in comp.lang.c.moderated throw in their $0.02 on this? Thanks. --
|
Tue, 24 Jun 2003 06:22:29 GMT |
|
 |
Richard B #2 / 22
|
 Calloc's zero initializing [was Re: 5 tap IIR Filter Impl]
Quote:
> On comp.dsp I posted the following:
> > Also, you could use calloc() > >instead of malloc() and skip the initialization step (calloc sets the > >array to zero). > "Since calloc'z zero fill is all bits zeros, it is guaranteed to yield the > value 0 for all integral types (including '\0' for character types). But > it does NOT guarantee usefull null pointer values (see Chapter 5) or > floating-point zero values." (C Programming FAQs by Steve Summit). Since > the x and y are pointers to type double, relying on calloc for zero > initial values will not result in portable code. > Klaus Bahner responded with this: > Isn't this statement a bit too theoretical?
No. Quote: > So I think, you will have a hard time in order to find a system where > float *x; > x = (float *) calloc ( LENGTH * sizeof(float));
Tsk. Don't cast the return value of *alloc(). You'll forget to #include <stdlib.h> next, and then where will you be? Quote: > /* initializes *x to +0.0 */ > is non portable code.
Not the point. The ISO Standard allows such systems, so whether you know any or not, there could be one tomorrow. Quote: > In my opinion the same yields for NULL pointers. I've never seen any C > compiler defining NULL different than "#define NULL (void *) 0x0", > whereby NULL is mapped to an integral type.
This is plain nonsense. Read the FAQ. Just because the null pointer is represented by an integral zero constant _in source_ doesn't mean that its internal representation is all-bits-zero. You really shouldn't confuse these levels. You might also want to consider that C doesn't _have_ to be compiled. A null pointer could be a struct in an interpreter, consisting of { base==null, length==-1, max==-1, name=="(null)" }. With padding to taste. A zero float could be a struct { mantissa==0, exponent==random, name=="x" }. Richard --
|
Wed, 25 Jun 2003 05:31:35 GMT |
|
 |
Klaus.Bah.. #3 / 22
|
 Calloc's zero initializing [was Re: 5 tap IIR Filter Impl]
Quote: > > /* initializes *x to +0.0 */ > > is non portable code. > Not the point. The ISO Standard allows such systems, so whether you know > any or not, there could be one tomorrow.
Well, so what's the point of calloc at all? Can't remember that the standard forces the internal representation of e.g. signed integers to be 2-complement numbers. (Or do I remember this again wrongly?) So, in case one of these tomorrow system uses for example integers which are not 2-complements but just adds an offset (so that 0 is represented by 0x80000000 for 32 bit values). Then the "initialization feature" of calloc will also fail for integral types. Klaus --
|
Sun, 29 Jun 2003 12:40:46 GMT |
|
 |
Fernando Gon #4 / 22
|
 Calloc's zero initializing [was Re: 5 tap IIR Filter Impl]
>> float *x; >> x = (float *) calloc ( LENGTH * sizeof(float)); >Tsk. Don't cast the return value of *alloc(). You'll forget to #include ><stdlib.h> next, and then where will you be? I usually cast pointers in that way, as x (in this example) is a pointer to float, and NOT a void pointer. I get "Warning: Nonportable pointer conversion" from Borland's Turbo C if I compile the same code without casting calloc's result. -- Fernando Gont
[Please remove ANTISPAM from my e-mail address if you want to send me e-mail] --
|
Sun, 29 Jun 2003 23:50:51 GMT |
|
 |
Richard B #5 / 22
|
 Calloc's zero initializing [was Re: 5 tap IIR Filter Impl]
Quote:
> > > /* initializes *x to +0.0 */ > > > is non portable code. > > Not the point. The ISO Standard allows such systems, so whether you > > know any or not, there could be one tomorrow. > Well, so what's the point of calloc at all? Can't remember that the > standard forces the internal representation of e.g. signed integers to > be 2-complement numbers. (Or do I remember this again wrongly?)
No, but it _does_ demand that all-bits-zero has value 0 for all _integer_ types, signed or unsigned. So calloc() can be used for integers. That's a limited function (I rarely if ever use calloc() myself), but it is a function. Quote: > So, in case one of these tomorrow system uses for example integers which > are not 2-complements but just adds an offset (so that 0 is represented > by 0x80000000 for 32 bit values).
No, that's not allowed. The non-negative values of any integer type must be represented in pure binary notation. Richard --
|
Mon, 30 Jun 2003 01:28:43 GMT |
|
 |
Christian B #6 / 22
|
 Calloc's zero initializing [was Re: 5 tap IIR Filter Impl]
Quote:
> > > /* initializes *x to +0.0 */ > > > is non portable code. > > Not the point. The ISO Standard allows such systems, so whether you > know > > any or not, there could be one tomorrow. > Well, so what's the point of calloc at all? Can't remember that the > standard forces the internal representation of e.g. signed integers to > be 2-complement numbers. (Or do I remember this again wrongly?)
According to the C99 standard, signed integers consist of value bits in a pure binary representation (so value bits = 0 mean the value is 0), a sign bit which changes the value if it is not zero, and possible other, unused, bits that are not part of the value but may create "trap representations". All bits zero can never be a legal value different from 0, but it could be a trap representation, that means something completely illegal. Quote: > Then the "initialization feature" of > calloc will also fail for integral types.
Exactly. calloc is guaranteed to "work" only for unsigned char. I personally don't know of any implementation where it doesn't initialize ints, floats, doubles and pointers to 0, but it still is not guaranteed by the C language standard. --
|
Mon, 30 Jun 2003 01:28:57 GMT |
|
 |
Richard B #7 / 22
|
 Calloc's zero initializing [was Re: 5 tap IIR Filter Impl]
Quote:
> >> float *x; > >> x = (float *) calloc ( LENGTH * sizeof(float)); > >Tsk. Don't cast the return value of *alloc(). You'll forget to #include > ><stdlib.h> next, and then where will you be? > I usually cast pointers in that way, as x (in this example) is a pointer to > float, and NOT a void pointer.
That is rather immaterial, since one can assign a void * to any other object pointer without any problems. That's what void *s are _for_, and it's why *alloc() now return a void * rather than a char * in the first place. The cast buys you nothing and can hide a serious error. There is no good reason to keep it. Quote: > I get "Warning: Nonportable pointer conversion" from Borland's Turbo C if I > compile the same code without casting calloc's result.
In that case, either: - you _have_ forgotten to #include <stdlib.h>, in which case you are invoking undefined behaviour like there's no tomorrow, or - you are running the compiler as a C++ compiler, or - the compiler is severely broken. Assigning a void * to _any_ object pointer should not give a diagnostic. Richard --
|
Mon, 30 Jun 2003 01:29:54 GMT |
|
 |
Jerry Avin #8 / 22
|
 Calloc's zero initializing [was Re: 5 tap IIR Filter Impl]
Quote:
> > > /* initializes *x to +0.0 */ > > > is non portable code. > > Not the point. The ISO Standard allows such systems, so whether you > know > > any or not, there could be one tomorrow. > Well, so what's the point of calloc at all? Can't remember that the > standard forces the internal representation of e.g. signed integers to > be 2-complement numbers. (Or do I remember this again wrongly?) > So, in case one of these tomorrow system uses for example integers which > are not 2-complements but just adds an offset (so that 0 is represented > by 0x80000000 for 32 bit values). Then the "initialization feature" of > calloc will also fail for integral types. > Klaus > --
How so? Aren't you confusing bit patterns with the entities that they represent? Ia system uses offset binary instead of twos complement, there is still a way to represent zero. The compiler will use that representation. I am reminded of the genius with a Master's in CS who asked me ("You're a hardware guy; maybe you know") how the hardware knows the difference between a char and a short on an 8-bit system. When I told him that that's a software issue, that hardware neither knows nor cares, he opined that I was too ignorant to be of use to him. (He was probably right about that!) Jerry -- Engineering is the art of making what you want from things you can get. ----------------------------------------------------------------------- --
|
Mon, 30 Jun 2003 13:31:43 GMT |
|
 |
Douglas A. Gwy #9 / 22
|
 Calloc's zero initializing [was Re: 5 tap IIR Filter Impl]
Quote:
> Well, so what's the point of calloc at all?
calloc is a legacy function. We standardized it since it was widely used. The fact is that it has always been misused to "zero-initialize" arrays of types for which all-0-bits might not represent a proper value; most C programmers learned not to use it for floating-point and pointer types, but few have encountered systems where all-0-bits is not a proper way to represent the vale 0 for integer types. Thus there hasn't been a problem in practice, despite the potential for one. --
|
Mon, 30 Jun 2003 13:32:47 GMT |
|
 |
NOSPAMd.. #10 / 22
|
 Calloc's zero initializing [was Re: 5 tap IIR Filter Impl]
Quote:
> > > > /* initializes *x to +0.0 */ > > > > is non portable code. > > > Not the point. The ISO Standard allows such systems, so whether you > > know > > > any or not, there could be one tomorrow. > > Well, so what's the point of calloc at all? Can't remember that the > > standard forces the internal representation of e.g. signed integers to > > be 2-complement numbers. (Or do I remember this again wrongly?) > According to the C99 standard, signed integers consist of value bits in a > pure binary representation (so value bits = 0 mean the value is 0), a sign > bit which changes the value if it is not zero, and possible other, unused, > bits that are not part of the value but may create "trap representations". > All bits zero can never be a legal value different from 0, but it could be > a trap representation, that means something completely illegal. > > Then the "initialization feature" of > > calloc will also fail for integral types. > Exactly. calloc is guaranteed to "work" only for unsigned char. > I personally don't know of any implementation where it doesn't initialize > ints, floats, doubles and pointers to 0, but it still is not guaranteed by > the C language standard. > --
While it is possible for signed integers to have unused bits, it would be exceptionally stupid for any implementation to make all bits 0 a trap representation for any integer type, even if it is theoretically permitted under C99. This would break all kinds of legacy C89 code that properly used calloc to initialize integers. This is in contrast to floating and pointer types, which were explicitly warned about in a C89 footnote in the description of calloc (and indeed, there are actual implementations where all bits zero is not a null pointer). Any vendor who would gratuitously make calloc useless on their platform without a damn good reason would face substantial market resistance. So I think it is practically safe to continue to use calloc for integer types, even if there is a theoretical possibility it might break. I'm not saying that there won't be implementations that have trap representations for integers - just that I don't expect all bits zero to ever be a trap representation. Dave W. -- Dave Wallace (Remove NOSPAM from my address to email me) It is quite humbling to realize that the storage occupied by the longest line from a typical Usenet posting is sufficient to provide a state space so vast that all the computation power in the world can not conquer it. --
|
Mon, 30 Jun 2003 14:06:52 GMT |
|
 |
Jack Klei #11 / 22
|
 Calloc's zero initializing [was Re: 5 tap IIR Filter Impl]
in comp.lang.c.moderated: Quote:
> >> float *x; > >> x = (float *) calloc ( LENGTH * sizeof(float)); > >Tsk. Don't cast the return value of *alloc(). You'll forget to #include > ><stdlib.h> next, and then where will you be? > I usually cast pointers in that way, as x (in this example) is a pointer to > float, and NOT a void pointer. > I get "Warning: Nonportable pointer conversion" from Borland's Turbo C if I > compile the same code without casting calloc's result.
In addition to Richard's perfectly correct suggestions, you could be using a version of Turbo C that predates the C89 standard, in which case malloc() returned a pointer to char which does require a cast to assign to any other pointer type. The first version of Turbo C was released in 1986. But most likely one of Richard's other suggestions is the cause. Jack Klein -- Home: http://jackklein.home.att.net --
|
Tue, 01 Jul 2003 09:32:07 GMT |
|
 |
Jack Klei #12 / 22
|
 Calloc's zero initializing [was Re: 5 tap IIR Filter Impl]
wrote in comp.lang.c.moderated: Quote:
> > > > /* initializes *x to +0.0 */ > > > > is non portable code. > > > Not the point. The ISO Standard allows such systems, so whether you > > > know any or not, there could be one tomorrow. > > Well, so what's the point of calloc at all? Can't remember that the > > standard forces the internal representation of e.g. signed integers to > > be 2-complement numbers. (Or do I remember this again wrongly?) > No, but it _does_ demand that all-bits-zero has value 0 for all > _integer_ types, signed or unsigned. So calloc() can be used for > integers. That's a limited function (I rarely if ever use calloc() > myself), but it is a function.
No to your no, it _does_ demand that all signed and unsigned integer types with a value of 0 have all _value_ bits 0. But all signed and unsigned integer types with the exception of unsigned char can also have padding bits (even signed char, in C99), and there is no guarantee that setting the padding bits to 0 does not create a trap representation. The _only_ data type that is guaranteed to be set to a value value of 0 with calloc or memset() to 0, is unsigned char. Period. Quote: > > So, in case one of these tomorrow system uses for example integers which > > are not 2-complements but just adds an offset (so that 0 is represented > > by 0x80000000 for 32 bit values). > No, that's not allowed. The non-negative values of any integer type must > be represented in pure binary notation. > Richard
Jack Klein -- Home: http://jackklein.home.att.net --
|
Tue, 01 Jul 2003 09:31:47 GMT |
|
 |
Jack Klei #13 / 22
|
 Calloc's zero initializing [was Re: 5 tap IIR Filter Impl]
comp.lang.c.moderated: Quote:
> > > > /* initializes *x to +0.0 */ > > > > is non portable code. > > > Not the point. The ISO Standard allows such systems, so whether you > > know > > > any or not, there could be one tomorrow. > > Well, so what's the point of calloc at all? Can't remember that the > > standard forces the internal representation of e.g. signed integers to > > be 2-complement numbers. (Or do I remember this again wrongly?) > > So, in case one of these tomorrow system uses for example integers which > > are not 2-complements but just adds an offset (so that 0 is represented > > by 0x80000000 for 32 bit values). Then the "initialization feature" of > > calloc will also fail for integral types. > > Klaus > > --
> How so? Aren't you confusing bit patterns with the entities that they > represent? Ia system uses offset binary instead of twos complement, > there is still a way to represent zero. The compiler will use that > representation.
This is not one of the possible pitfalls. C (and C++, for that matter) require a pure binary notation for integer types. Offset binary is impossible in a conforming C implementation. The issue is padding bits. Quote: > I am reminded of the genius with a Master's in CS who asked me ("You're > a hardware guy; maybe you know") how the hardware knows the difference > between a char and a short on an 8-bit system. When I told him that > that's a software issue, that hardware neither knows nor cares, he > opined that I was too ignorant to be of use to him. (He was probably > right about that!) > Jerry > -- > Engineering is the art of making what you want from things you can get. > -----------------------------------------------------------------------
Jack Klein -- Home: http://jackklein.home.att.net --
|
Tue, 01 Jul 2003 09:31:55 GMT |
|
 |
Christian B #14 / 22
|
 Calloc's zero initializing [was Re: 5 tap IIR Filter Impl]
Quote:
> While it is possible for signed integers to have unused bits, it > would be exceptionally stupid for any implementation to make > all bits 0 a trap representation for any integer type, even > if it is theoretically permitted under C99. This would break > all kinds of legacy C89 code that properly used calloc to > initialize integers. This is in contrast to floating and pointer > types, which were explicitly warned about in a C89 footnote > in the description of calloc (and indeed, there are actual > implementations where all bits zero is not a null pointer). > Any vendor who would gratuitously make calloc useless > on their platform without a damn good reason would face > substantial market resistance. So I think it is practically > safe to continue to use calloc for integer types, even > if there is a theoretical possibility it might break.
What about a compiler that is specifically designed to find bugs in your code? A compiler that has the attitude "if your code is broken, I'll break it". This compiler would make lots of programs crash, yet it would be damned useful. --
|
Tue, 01 Jul 2003 09:32:45 GMT |
|
 |
Douglas A. Gwy #15 / 22
|
 Calloc's zero initializing [was Re: 5 tap IIR Filter Impl]
Quote:
> While it is possible for signed integers to have unused bits, it > would be exceptionally stupid for any implementation to make > all bits 0 a trap representation for any integer type, even > if it is theoretically permitted under C99. This would break > all kinds of legacy C89 code that properly used calloc to > initialize integers. This is in contrast to floating and pointer > types, which were explicitly warned about in a C89 footnote > in the description of calloc (and indeed, there are actual > implementations where all bits zero is not a null pointer). > Any vendor who would gratuitously make calloc useless > on their platform without a damn good reason would face > substantial market resistance. So I think it is practically > safe to continue to use calloc for integer types, even > if there is a theoretical possibility it might break.
Of course implementors would not gratuitously make a special effort to "break" widespread calloc usage. However, there might be compelling reasons for the all-0 bit representation to be a "trap" representation on some architectures, if that happened to be the natural behavior of the hardware. For example, consider a double-word representation for long or long long, where the sign bit of the LSW needs to be 1 in order to support the most efficient machine code for signed arithmetic. (Notice that in this case a "trap representation" might not actually *trap*, but would yield wrong results in computations.) --
|
Wed, 02 Jul 2003 01:31:29 GMT |
|
|
Page 1 of 2
|
[ 22 post ] |
|
Go to page:
[1]
[2] |
|