Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #21648 > unrolled thread
| Started by | Jean-Christophe <5.d@free.fr> |
|---|---|
| First post | 2012-06-02 02:49 -0700 |
| Last post | 2012-06-02 17:50 +0000 |
| Articles | 20 on this page of 61 — 17 participants |
Back to article view | Back to comp.lang.c
Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 02:49 -0700
Re: Q: Local variables initialization shortcut. China Blue Max <chine.bleu@yahoo.com> - 2012-06-02 03:03 -0700
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 03:17 -0700
Re: Q: Local variables initialization shortcut. jacob navia <jacob@spamsink.net> - 2012-06-02 12:06 +0200
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 03:25 -0700
Re: Q: Local variables initialization shortcut. James Kuyper <jameskuyper@verizon.net> - 2012-06-02 10:59 -0400
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 13:02 -0700
Re: Q: Local variables initialization shortcut. Keith Thompson <kst-u@mib.org> - 2012-06-02 14:51 -0700
Re: Q: Local variables initialization shortcut. Ian Collins <ian-news@hotmail.com> - 2012-06-02 22:10 +1200
Re: Q: Local variables initialization shortcut. jt@toerring.de (Jens Thoms Toerring) - 2012-06-02 10:31 +0000
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 03:59 -0700
Re: Q: Local variables initialization shortcut. jt@toerring.de (Jens Thoms Toerring) - 2012-06-02 11:55 +0000
Re: Q: Local variables initialization shortcut. pete <pfiland@mindspring.com> - 2012-06-02 08:15 -0400
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 05:37 -0700
Re: Q: Local variables initialization shortcut. jt@toerring.de (Jens Thoms Toerring) - 2012-06-02 13:35 +0000
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 06:47 -0700
Re: Q: Local variables initialization shortcut. "BartC" <bc@freeuk.com> - 2012-06-02 15:08 +0100
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 07:37 -0700
Re: Q: Local variables initialization shortcut. "BartC" <bc@freeuk.com> - 2012-06-02 16:17 +0100
Re: Q: Local variables initialization shortcut. "BartC" <bc@freeuk.com> - 2012-06-02 19:02 +0100
Re: Q: Local variables initialization shortcut. jt@toerring.de (Jens Thoms Toerring) - 2012-06-02 17:39 +0000
Re: Q: Local variables initialization shortcut. Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-06-02 15:27 -0400
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 12:58 -0700
Re: Q: Local variables initialization shortcut. Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-06-02 16:15 -0400
Re: Q: Local variables initialization shortcut. David Brown <david.brown@hesbynett.no> - 2012-06-03 15:27 -0500
Re: Q: Local variables initialization shortcut. Noob <root@localhost> - 2012-06-05 09:12 +0200
Re: Q: Local variables initialization shortcut. David Brown <david@westcontrol.removethisbit.com> - 2012-06-05 09:21 +0200
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 12:53 -0700
Re: Q: Local variables initialization shortcut. "BartC" <bc@freeuk.com> - 2012-06-02 21:16 +0100
Re: Q: Local variables initialization shortcut. jt@toerring.de (Jens Thoms Toerring) - 2012-06-02 21:18 +0000
Re: Q: Local variables initialization shortcut. Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-06-02 17:38 -0400
Re: Q: Local variables initialization shortcut. jt@toerring.de (Jens Thoms Toerring) - 2012-06-02 22:15 +0000
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-03 00:51 -0700
Re: Q: Local variables initialization shortcut. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-06-03 11:46 -0700
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-03 00:13 -0700
Re: Q: Local variables initialization shortcut. Keith Thompson <kst-u@mib.org> - 2012-06-02 14:50 -0700
Re: Q: Local variables initialization shortcut. David Brown <david.brown@hesbynett.no> - 2012-06-03 15:34 -0500
Re: Q: Local variables initialization shortcut. David Brown <david.brown@hesbynett.no> - 2012-06-03 15:25 -0500
Re: Q: Local variables initialization shortcut. Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-06-02 08:46 -0400
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 05:46 -0700
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 05:53 -0700
Re: Q: Local variables initialization shortcut. Ike Naar <ike@sverige.freeshell.org> - 2012-06-02 17:08 +0000
Re: Q: Local variables initialization shortcut. "io_x" <a@b.c.invalid> - 2012-06-03 10:33 +0200
Re: Q: Local variables initialization shortcut. "io_x" <a@b.c.invalid> - 2012-06-03 11:32 +0200
Re: Q: Local variables initialization shortcut. pete <pfiland@mindspring.com> - 2012-06-02 08:03 -0400
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 05:18 -0700
Re: Q: Local variables initialization shortcut. "io_x" <a@b.c.invalid> - 2012-06-03 10:32 +0200
Re: Q: Local variables initialization shortcut. "BartC" <bc@freeuk.com> - 2012-06-02 11:45 +0100
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 04:17 -0700
Re: Q: Local variables initialization shortcut. "BartC" <bc@freeuk.com> - 2012-06-02 12:40 +0100
Re: Q: Local variables initialization shortcut. "BartC" <bc@freeuk.com> - 2012-06-02 12:51 +0100
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 04:57 -0700
Re: Q: Local variables initialization shortcut. "BartC" <bc@freeuk.com> - 2012-06-02 14:00 +0100
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 06:12 -0700
Re: Q: Local variables initialization shortcut. Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-06-02 09:58 -0400
Re: Q: Local variables initialization shortcut. David Brown <david.brown@hesbynett.no> - 2012-06-03 15:41 -0500
Re: Q: Local variables initialization shortcut. Robert Wessel <robertwessel2@yahoo.com> - 2012-06-02 11:45 -0500
Re: Q: Local variables initialization shortcut. Noob <root@localhost> - 2012-06-02 16:05 +0200
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 07:48 -0700
Re: Q: Local variables initialization shortcut. "BartC" <bc@freeuk.com> - 2012-06-02 18:31 +0100
Re: Q: Local variables initialization shortcut. jt@toerring.de (Jens Thoms Toerring) - 2012-06-02 17:50 +0000
Page 1 of 4 [1] 2 3 4 Next page →
| From | Jean-Christophe <5.d@free.fr> |
|---|---|
| Date | 2012-06-02 02:49 -0700 |
| Subject | Q: Local variables initialization shortcut. |
| Message-ID | <5835baa1-db3f-4b81-a9e9-3ea20a632ba8@w24g2000vby.googlegroups.com> |
Hi all,
The function f() has some local (double)
which should all be initialized to zero :
a = b = c = ... = y = z = 0.0;
Can I use a shortcut like this :
memset( &a, 0, number_of_variables * sizeof(double) );
If yes, can I do this :
memset( &a, 0, (&z - &a + sizeof(double)) );
Like this :
void f(void)
{
double a,b,c,d,...,x,y,z;
memset( &a, 0, (unsigned int)( &z - &a + sizeof(double) ) );
...
}
--------
PS :
Of course the # of variables is not always 26,
that's why I want an easy way to implement initialization to zero.
[toc] | [next] | [standalone]
| From | China Blue Max <chine.bleu@yahoo.com> |
|---|---|
| Date | 2012-06-02 03:03 -0700 |
| Message-ID | <chine.bleu-0321A0.03030502062012@news.eternal-september.org> |
| In reply to | #21648 |
In article <5835baa1-db3f-4b81-a9e9-3ea20a632ba8@w24g2000vby.googlegroups.com>, Jean-Christophe <5.d@free.fr> wrote: > Hi all, > > The function f() has some local (double) > which should all be initialized to zero : > > a = b = c = ... = y = z = 0.0; > > Can I use a shortcut like this : No. You cannot assume anything about assignment of variables to memory. -- My name Indigo Montoya. | The Dude abides. You flamed my father. | I'm whoever you want me to be. Prepare to be spanked. | Annoying Usenet one post at a time. Stop posting that! | At least I can stay in character.
[toc] | [prev] | [next] | [standalone]
| From | Jean-Christophe <5.d@free.fr> |
|---|---|
| Date | 2012-06-02 03:17 -0700 |
| Message-ID | <abf174cc-00a7-47c3-bb43-75abc138c14c@6g2000vbv.googlegroups.com> |
| In reply to | #21649 |
On 2 juin, 12:03, China Blue Max : | Jean-Christophe : | Can I use a shortcut like this (...) > No. > You cannot assume anything about assignment of variables to memory. *sigh* ... okay, thanks !
[toc] | [prev] | [next] | [standalone]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2012-06-02 12:06 +0200 |
| Message-ID | <jqcoij$ifu$1@speranza.aioe.org> |
| In reply to | #21648 |
Le 02/06/12 11:49, Jean-Christophe a écrit :
> Hi all,
>
> The function f() has some local (double)
> which should all be initialized to zero :
>
> a = b = c = ... = y = z = 0.0;
>
> Can I use a shortcut like this :
>
> memset(&a, 0, number_of_variables * sizeof(double) );
>
> If yes, can I do this :
>
> memset(&a, 0, (&z -&a + sizeof(double)) );
>
> Like this :
>
> void f(void)
> {
> double a,b,c,d,...,x,y,z;
>
> memset(&a, 0, (unsigned int)(&z -&a + sizeof(double) ) );
>
> ...
> }
>
> --------
>
> PS :
> Of course the # of variables is not always 26,
> that's why I want an easy way to implement initialization to zero.
>
No, in general you can't. The compiler may align the double variables at
a 16 byte boundary for instance, for performance reasons. That would
mean that the compiler would leave 8 bytes unused between each variable.
Another problem could be that the compiler doesn't store those variables
in a contiguos fashion but interleaves variables with other data (maybe
because alignment reasons)
An easy solution to your problem is:
#include <stdio.h>
int main(void) {
int i;
for (i='a'; i<= 'z'; i++) {
printf("\t%c = 0.0;\n",i);
}
}
Redirect the output to a file and insert that file
into your source code
:-)
[toc] | [prev] | [next] | [standalone]
| From | Jean-Christophe <5.d@free.fr> |
|---|---|
| Date | 2012-06-02 03:25 -0700 |
| Message-ID | <f6919deb-bb2f-431b-93a2-0a2628708797@d17g2000vbv.googlegroups.com> |
| In reply to | #21650 |
On 2 juin, 12:06, jacob navia :
| Can I use a shortcut like this (...)
> No, in general you can't. The compiler may align the double variables at
> a 16 byte boundary for instance, for performance reasons. That would
> mean that the compiler would leave 8 bytes unused between each variable.
> Another problem could be that the compiler doesn't store those variables
> in a contiguos fashion but interleaves variables with other data (maybe
> because alignment reasons)
Okay, thanks.
Since these variables are located in the stack,
is there a way to FORCE the compiler to align them,
using a compiler directive or something ?
> An easy solution to your problem is:
> #include <stdio.h>
> int main(void) {
> int i;
> for (i='a'; i<= 'z'; i++) {
> printf("\t%c = 0.0;\n",i);
> }
> }
> Redirect the output to a file and insert
> that file into your source code :-)
That's not what I call 'easy'.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-06-02 10:59 -0400 |
| Message-ID | <jqd9oe$o5m$1@dont-email.me> |
| In reply to | #21653 |
On 06/02/2012 06:25 AM, Jean-Christophe wrote:
> On 2 juin, 12:06, jacob navia :
>
> | Can I use a shortcut like this (...)
>
>> No, in general you can't. The compiler may align the double variables at
>> a 16 byte boundary for instance, for performance reasons. That would
>> mean that the compiler would leave 8 bytes unused between each variable.
>> Another problem could be that the compiler doesn't store those variables
>> in a contiguos fashion but interleaves variables with other data (maybe
>> because alignment reasons)
>
> Okay, thanks.
>
> Since these variables are located in the stack,
> is there a way to FORCE the compiler to align them,
> using a compiler directive or something ?
Yes - but it's not a compiler directive, it's "something" called an
array. Instead of a, b, c, ..., z, use arr[0], arr[1], arr[2], ...,
arr[25]. Then you could use memset() on the entire array.
Keep in mind that memset() set the specified number of bytes,
interpreted as unsigned char, to the specified value. If that value is
0, on many systems that will cause the doubles to have a value of 0.0.
In C99, if __STDC_IEC_559__ is pre-defined by the implementation, that's
guaranteed to be true. However, if using C90, or if __STDC_IEC_559__ is
not pre-defined, an implementation is allowed to use a floating point
representation were all-bits-0 represents some other number entirely, or
even a NaN. It could even be a trap representation, in which case any
attempt to retrieve the value of the double objects after calling
memset() has undefined behavior.
The easiest way to portably guarantee that your floating point values
are zero-initialized is to do so explicitly:
double a=0, b=0, c=0, ..., z=0;
if you follow my suggestion, and use an array, you can save a lot of typing:
double arr[26] = {0};
You should understand what that does: it explicitly sets arr[0] to 0,
and implicitly zero-initializes the other 25 elements to 0. There's a
common misunderstanding of code like this; the easiest way to correct
that misunderstanding it to consider the following alternative:
double arr[26] = {1};
That does NOT set ever element of arr to 1. It explicitly sets arr[0] to
1, but the remaining 25 elements would still be implicitly zero-initialized.
>> An easy solution to your problem is:
>> #include <stdio.h>
>> int main(void) {
>> int i;
>> for (i='a'; i<= 'z'; i++) {
>> printf("\t%c = 0.0;\n",i);
>> }
>> }
>> Redirect the output to a file and insert
>> that file into your source code :-)
>
> That's not what I call 'easy'.
The :-) was your clue that it was a joke. He was basically hinting at
the 'a=0, b=0, c=0' approach I described above.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Jean-Christophe <5.d@free.fr> |
|---|---|
| Date | 2012-06-02 13:02 -0700 |
| Message-ID | <28f08325-a2ff-4c39-b6a5-8abfaf9ad93a@d17g2000vbv.googlegroups.com> |
| In reply to | #21689 |
On 2 juin, 16:59, James Kuyper <jameskuy...@verizon.net> wrote: > > Since these variables are located in the stack, > > is there a way to FORCE the compiler to align them, > > using a compiler directive or something ? > Yes - but it's not a compiler directive So it's "No" since it's not a compiler directive.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-06-02 14:51 -0700 |
| Message-ID | <lnvcj9fklo.fsf@nuthaus.mib.org> |
| In reply to | #21709 |
Jean-Christophe <5.d@free.fr> writes:
> On 2 juin, 16:59, James Kuyper <jameskuy...@verizon.net> wrote:
>> > Since these variables are located in the stack,
>> > is there a way to FORCE the compiler to align them,
>> > using a compiler directive or something ?
>
>> Yes - but it's not a compiler directive
>
> So it's "No" since it's not a compiler directive.
It's "Yes" since it's an "or something".
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2012-06-02 22:10 +1200 |
| Message-ID | <a2u74aF47aU1@mid.individual.net> |
| In reply to | #21648 |
On 06/ 2/12 09:49 PM, Jean-Christophe wrote:
> Hi all,
>
> The function f() has some local (double)
> which should all be initialized to zero :
>
> a = b = c = ... = y = z = 0.0;
>
> Can I use a shortcut like this :
>
> memset(&a, 0, number_of_variables * sizeof(double) );
>
> If yes, can I do this :
>
> memset(&a, 0, (&z -&a + sizeof(double)) );
>
> Like this :
>
> void f(void)
> {
> double a,b,c,d,...,x,y,z;
>
> memset(&a, 0, (unsigned int)(&z -&a + sizeof(double) ) );
>
> ...
> }
>
> --------
>
> PS :
> Of course the # of variables is not always 26,
> that's why I want an easy way to implement initialization to zero.
If they need to be initialised, declare and initialise them when they
are first used.
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2012-06-02 10:31 +0000 |
| Message-ID | <a2u8bhF5u8U1@mid.uni-berlin.de> |
| In reply to | #21648 |
Jean-Christophe <5.d@free.fr> wrote:
> The function f() has some local (double)
> which should all be initialized to zero :
> double a,b,c,d,...,x,y,z;
> a = b = c = ... = y = z = 0.0;
> Can I use a shortcut like this :
> memset( &a, 0, number_of_variables * sizeof(double) );
Your idea has a number of problems: for once, while it is
not unlikely that they are all in consecutive memory lo-
cations, that's not guaranteed - the simplest practical
reason would be that the compiler finds that one or more
of the variables is not really needs to be kept in memory
and can be optimized to reside in a CPU register only. Se-
cond, even if that wouldn't be an issue, there is no reason
at all that 'a' should be at the lowest address - quite
often the variable defined last is the one with the lowest
address - this is completely at the discretion of the com-
piler. Finally not on all systems a 0.0 value is represen-
ted by all bits set to zero.
> If yes, can I do this :
> memset( &a, 0, (&z - &a + sizeof(double)) );
'&z - &a' isn't legal - you can only subtract addresses
of locations within a single object (e.g. an array),
everything else is undefined behaviour, And even if
disregarding this and assuming that 'a' is at the lowest
and 'z' at the highest address, '&z - &a' will be the
number of variable between 'a' and 'z' (25) and not the
number of bytes used in between, so you would have to
multiply by the size of a double.
Since you try to treat these variables (at least in the
respect of initialization) as if they make up an array,
would it be possible to atually use an array? Then ini-
tialization is rather simple:
double a2z[ 26 ] = { 0.0 };
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
[toc] | [prev] | [next] | [standalone]
| From | Jean-Christophe <5.d@free.fr> |
|---|---|
| Date | 2012-06-02 03:59 -0700 |
| Message-ID | <4f89a691-f680-4dbc-bdbc-363450ccc001@b26g2000vbt.googlegroups.com> |
| In reply to | #21654 |
On 2 juin, 12:31, j...@toerring.de :
> Your idea has a number of problems: for once, while it is
> not unlikely that they are all in consecutive memory lo-
> cations, that's not guaranteed - the simplest practical
> reason would be that the compiler finds that one or more
> of the variables is not really needs to be kept in memory
> and can be optimized to reside in a CPU register only. Se-
> cond, even if that wouldn't be an issue, there is no reason
> at all that 'a' should be at the lowest address - quite
> often the variable defined last is the one with the lowest
> address - this is completely at the discretion of the com-
> piler.
Okay.
> Finally not on all systems a 0.0 value
> is represented by all bits set to zero.
Well, at least this is the case for
Windows float and double, isn't it ?
> '&z - &a' isn't legal - you can only subtract addresses
> of locations within a single object (e.g. an array),
I've done it many times and it always worked fine :
&a is the address of 'a' so it's its memory location.
Except for this actual example (when variables are stored
in stack w/ their adresses allocated by the compiler)
if the location of 'a' thru 'z' are well stored
(i.e, like in an array) then the following code works fine :
unsigned int size = (unsigned int)( &z - &a );
> everything else is undefined behaviour, And even if
> disregarding this and assuming that 'a' is at the lowest
> and 'z' at the highest address, '&z - &a' will be the
> number of variable between 'a' and 'z' (25) and not the
> number of bytes used in between, so you would have to
> multiply by the size of a double.
Hum, no : if &z is the highest address
and &a is the lowest address then (&z - &a)
is the number of bytes (less one sizeof) and not the
number of variables (unless 'a' and 'z' are chars)
> Since you try to treat these variables (at least in the
> respect of initialization) as if they make up an array,
> would it be possible to atually use an array? Then ini-
> tialization is rather simple:
> double a2z[ 26 ] = { 0.0 };
Yes of course, but the problem is that these
variables names are not as simple as 'a'...'z'
and they are used individually (am I clear here ?)
So then, to use your suggestion I should do something like
// declare & init
#define VAR_THIS d[0]
#define VAR_THAT d[1]
#define VAR_SOMETHING d[2]
... etc ...
#define VAR_MAX 10 // for instance
double d[VAR_MAX];
memset( d, 0, VAR_MAX * sizeof(d[0]) );
// using variables
VAR_THIS = ... ;
VAR_THAT = ... ;
x = ... VAR_THIS ... VAR_THAT ... ;
... but then, to write the whole set
of #define looks a bit heavy to me !
Thanks, Jens.
[toc] | [prev] | [next] | [standalone]
| From | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2012-06-02 11:55 +0000 |
| Message-ID | <a2uda9F4vcU1@mid.uni-berlin.de> |
| In reply to | #21657 |
Jean-Christophe <5.d@free.fr> wrote:
> On 2 juin, 12:31, j...@toerring.de :
> > Finally not on all systems a 0.0 value
> > is represented by all bits set to zero.
> Well, at least this is the case for
> Windows float and double, isn't it ?
Probably, since all hardware on Windows seem to be using
the very common IEEE 754 format for floating points. But
that isn't something required by the C standard, some sys-
tems may use a different bit representation for floating
points.
> > '&z - &a' isn't legal - you can only subtract addresses
> > of locations within a single object (e.g. an array),
> I've done it many times and it always worked fine :
> &a is the address of 'a' so it's its memory location.
Well, you were lucky. The standard doesn't define what
the result of subtracting pointers not within the same
object is (or, in the case of arrays, one beyond the
end of the array), so you are relying on whatever your
compiler makes out of it. Some other compiler might
give you a different result.
> Except for this actual example (when variables are stored
> in stack w/ their adresses allocated by the compiler)
There also is no requirement for a stack in the C stan-
dard. Most (or probably all) compilers will employ
something stack-like for local variables, but that is
a decision the compiler writer makes, not something
prescribed by the standard.
> if the location of 'a' thru 'z' are well stored
> (i.e, like in an array) then the following code works fine :
> unsigned int size = (unsigned int)( &z - &a );
Yes, it may seem to work on your system with the specific
compiler you are using. If you want your program to work
only on that system and with that compiler then this is
probably all fine, just dont expect it to work anymore
under different circumstances.
> > everything else is undefined behaviour, And even if
> > disregarding this and assuming that 'a' is at the lowest
> > and 'z' at the highest address, '&z - &a' will be the
> > number of variable between 'a' and 'z' (25) and not the
> > number of bytes used in between, so you would have to
> > multiply by the size of a double.
> Hum, no : if &z is the highest address
> and &a is the lowest address then (&z - &a)
> is the number of bytes (less one sizeof) and not the
> number of variables (unless 'a' and 'z' are chars)
That may well be the case. Since you are relying on un-
defined behaviour everything you get is "right". Just for
the fun of it: on my system (x86-64 Linux and with gcc)
the output of this program
#include <stdio.h>
int main( void )
{
double a, b;
printf( "%d\n", ( int ) ( &a - &b ) );
return 0;
}
is -1. So obviously at least some of the deductions you
were led to make by the behaviour on your system aren't
valid from what I see on my machine. And that's quite
ok since the behaviour of that program isn't defined,
so whatever the output is is correct. (And I have de-
finitely worked with machines were variables defined
later had lower addresses).
For even more giggles take this program:
#include <stdio.h>
int main( void )
{
double a, b, c;
printf( "%d\n", ( int ) ( &a - &c ) );
return 0;
}
The output on my machine is still -1...
But I am a bit puzzled - I would expect the difference
between two pointers of the same type to be number of
variables of that type in between, not the number of
bytes. Otherwise the behaviour (while undefined) would
be even more weird on your machine since e.g. for
arrays you can rely on the difference between the
addresses of two of its elements to be the number of
elements in between. But then, again, the moment you
do something undefined everything can happen.
> > Since you try to treat these variables (at least in the
> > respect of initialization) as if they make up an array,
> > would it be possible to atually use an array? Then ini-
> > tialization is rather simple:
> > double a2z[ 26 ] = { 0.0 };
> Yes of course, but the problem is that these
> variables names are not as simple as 'a'...'z'
> and they are used individually (am I clear here ?)
> So then, to use your suggestion I should do something like
> // declare & init
> #define VAR_THIS d[0]
> #define VAR_THAT d[1]
> #define VAR_SOMETHING d[2]
> ... etc ...
> #define VAR_MAX 10 // for instance
> double d[VAR_MAX];
> memset( d, 0, VAR_MAX * sizeof(d[0]) );
> // using variables
> VAR_THIS = ... ;
> VAR_THAT = ... ;
> x = ... VAR_THIS ... VAR_THAT ... ;
> ... but then, to write the whole set
> of #define looks a bit heavy to me !
Of course, this is the probably even worse than
writing
a = b = c = .... = z = 0.0;
since it's much harder to understand. The only conclusion
is that what you want to do can't be done in a portable
fashion in C.
Refards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
[toc] | [prev] | [next] | [standalone]
| From | pete <pfiland@mindspring.com> |
|---|---|
| Date | 2012-06-02 08:15 -0400 |
| Message-ID | <4FCA03D2.4AB8@mindspring.com> |
| In reply to | #21662 |
Jens Thoms Toerring wrote:
>
> Jean-Christophe <5.d@free.fr> wrote:
> > On 2 juin, 12:31, j...@toerring.de :
> > > '&z - &a' isn't legal - you can only subtract addresses
> > > of locations within a single object (e.g. an array),
>
> > I've done it many times and it always worked fine :
> > &a is the address of 'a' so it's its memory location.
>
> Well, you were lucky. The standard doesn't define what
> the result of subtracting pointers not within the same
> object is (or, in the case of arrays, one beyond the
> end of the array), so you are relying on whatever your
> compiler makes out of it. Some other compiler might
> give you a different result.
>
> > Except for this actual example (when variables are stored
> > in stack w/ their adresses allocated by the compiler)
>
> There also is no requirement for a stack in the C stan-
> dard. Most (or probably all) compilers will employ
> something stack-like for local variables, but that is
> a decision the compiler writer makes, not something
> prescribed by the standard.
>
> > if the location of 'a' thru 'z' are well stored
> > (i.e, like in an array) then the following code works fine :
> > unsigned int size = (unsigned int)( &z - &a );
>
> Yes, it may seem to work on your system with the specific
> compiler you are using. If you want your program to work
> only on that system and with that compiler then this is
> probably all fine, just dont expect it to work anymore
> under different circumstances.
>
> > > everything else is undefined behaviour, And even if
> > > disregarding this and assuming that 'a' is at the lowest
> > > and 'z' at the highest address, '&z - &a' will be the
> > > number of variable between 'a' and 'z' (25) and not the
> > > number of bytes used in between, so you would have to
> > > multiply by the size of a double.
>
> > Hum, no : if &z is the highest address
> > and &a is the lowest address then (&z - &a)
> > is the number of bytes (less one sizeof) and not the
> > number of variables (unless 'a' and 'z' are chars)
>
> That may well be the case. Since you are relying on un-
> defined behaviour everything you get is "right". Just for
> the fun of it: on my system (x86-64 Linux and with gcc)
> the output of this program
>
> #include <stdio.h>
> int main( void )
> {
> double a, b;
> printf( "%d\n", ( int ) ( &a - &b ) );
> return 0;
> }
>
> is -1. So obviously at least some of the deductions you
> were led to make by the behaviour on your system aren't
> valid from what I see on my machine. And that's quite
> ok since the behaviour of that program isn't defined,
> so whatever the output is is correct. (And I have de-
> finitely worked with machines were variables defined
> later had lower addresses).
>
> For even more giggles take this program:
>
> #include <stdio.h>
> int main( void )
> {
> double a, b, c;
> printf( "%d\n", ( int ) ( &a - &c ) );
> return 0;
> }
>
> The output on my machine is still -1...
>
> But I am a bit puzzled - I would expect the difference
> between two pointers of the same type to be number of
> variables of that type in between, not the number of
> bytes. Otherwise the behaviour (while undefined) would
> be even more weird on your machine since e.g. for
> arrays you can rely on the difference between the
> addresses of two of its elements to be the number of
> elements in between. But then, again, the moment you
> do something undefined everything can happen.
On the machine that I am using,
the following program outputs a pair of 1's.
#include <stdio.h>
int
main( void )
{
{
double a, b;
printf( "%d\n", ( int ) ( &a - &b ) );
}
{
double b, a;
printf( "%d\n", ( int ) ( &a - &b ) );
}
return 0;
}
--
pete
[toc] | [prev] | [next] | [standalone]
| From | Jean-Christophe <5.d@free.fr> |
|---|---|
| Date | 2012-06-02 05:37 -0700 |
| Message-ID | <0ecf3c52-be95-4a37-a6f0-42469d378f1e@m3g2000vbl.googlegroups.com> |
| In reply to | #21662 |
On 2 juin, 13:55, j...@toerring.de (Jens Thoms Toerring) wrote:
> > > Finally not on all systems a 0.0 value
> > > is represented by all bits set to zero.
> > Well, at least this is the case for
> > Windows float and double, isn't it ?
> Probably, since all hardware on Windows seem to be using
> the very common IEEE 754 format for floating points. But
> that isn't something required by the C standard, some sys-
> tems may use a different bit representation for floating
> points.
Ok.
> > > '&z - &a' isn't legal - you can only subtract addresses
> > > of locations within a single object (e.g. an array),
> > I've done it many times and it always worked fine :
> > &a is the address of 'a' so it's its memory location.
> Well, you were lucky. The standard doesn't define what
> the result of subtracting pointers not within the same
> object is (or, in the case of arrays, one beyond the
> end of the array), so you are relying on whatever your
> compiler makes out of it. Some other compiler might
> give you a different result.
Ok, I'll remember that.
> > Except for this actual example (when variables are stored
> > in stack w/ their adresses allocated by the compiler)
> There also is no requirement for a stack in the C stan-
> dard. Most (or probably all) compilers will employ
> something stack-like for local variables, but that is
> a decision the compiler writer makes, not something
> prescribed by the standard.
Ok.
> > if the location of 'a' thru 'z' are well stored
> > (i.e, like in an array) then the following code works fine :
> > unsigned int size = (unsigned int)( &z - &a );
> Yes, it may seem to work on your system with the specific
> compiler you are using. If you want your program to work
> only on that system and with that compiler then this is
> probably all fine, just dont expect it to work anymore
> under different circumstances.
Right. This is clumsy.
> > if &z is the highest address
> > and &a is the lowest address then (&z - &a)
> > is the number of bytes (less one sizeof) and not the
> > number of variables (unless 'a' and 'z' are chars)
> That may well be the case. Since you are relying on un-
> defined behaviour everything you get is "right". Just for
> the fun of it: on my system (x86-64 Linux and with gcc)
> the output of this program
> #include <stdio.h>
> int main( void )
> { double a, b;
> printf( "%d\n", ( int ) ( &a - &b ) );
> return 0;
> }
> is -1. So obviously at least some of the deductions you
> were led to make by the behaviour on your system aren't
> valid from what I see on my machine. And that's quite
> ok since the behaviour of that program isn't defined,
> so whatever the output is is correct. (And I have de-
> finitely worked with machines were variables defined
> later had lower addresses).
> For even more giggles take this program:
> #include <stdio.h>
> int main( void )
> { double a, b, c;
> printf( "%d\n", ( int ) ( &a - &c ) );
> return 0;
> }
> The output on my machine is still -1...
> But I am a bit puzzled - I would expect the difference
> between two pointers of the same type to be number of
> variables of that type in between, not the number of
> bytes.
You are right because you're talking about *pointers* :
int i;
double d1, d2, *a, *b;
a = &d1;
b = &d2;
i = (int)( b - a ); // assuming &d2 > &d1
then i == 1 // number of variables
because it's a difference of pointers
of a given variable type.
This is a different matter than :
int i;
double d1, d2;
i = (int)( &d2 - &d1 ); // assuming &d2 > &d1
then i == sizeof(double) // number of bytes
because it's a difference of addresses
whatever the variable type is.
> > ... but then, to write the whole set
> > of #define looks a bit heavy to me !
> Of course, this is the probably even worse than writing
> a = b = c = .... = z = 0.0;
> since it's much harder to understand. The only conclusion
> is that what you want to do can't be done in a portable
> fashion in C.
All right then.
I understand I made the error of expanding my knowledge
of 'micro-controllers' C compilers to the 'PC' C compilers.
Some things won't work at all, and if they do
it's even worse because it's just luck.
Thanks for taking time.
[toc] | [prev] | [next] | [standalone]
| From | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2012-06-02 13:35 +0000 |
| Message-ID | <a2uj5rFvv1U1@mid.uni-berlin.de> |
| In reply to | #21667 |
Jean-Christophe <5.d@free.fr> wrote:
> On 2 juin, 13:55, j...@toerring.de (Jens Thoms Toerring) wrote:
> You are right because you're talking about *pointers* :
> int i;
> double d1, d2, *a, *b;
> a = &d1;
> b = &d2;
> i = (int)( b - a ); // assuming &d2 > &d1
> then i == 1 // number of variables
> because it's a difference of pointers
> of a given variable type.
> This is a different matter than :
> int i;
> double d1, d2;
> i = (int)( &d2 - &d1 ); // assuming &d2 > &d1
> then i == sizeof(double) // number of bytes
> because it's a difference of addresses
> whatever the variable type is.
I don't agree - you are subtracting adresses and, as
long as you don't cross the border of undefined beha-
viour, it doesn't matter if you directly subtract the
addresses of two variables or first store those addres-
ses in pointers and then subtract their values. All what
(at least when used as defined by the standard, i.e.
when subtracting the addresses of elements of an array)
is the type of the elements. Thus
double a[ 10 ];
double * ap2 = &a[ 2 ],
* ap7 = &a[ 7 ];
printf( "%d %d\n", ( int ) ( &a[ 7 ] - &a[ 2 ] ),
( int ) ( ap7 - ap2 ) );
will always output "5 5", the number of elements in
between (and you're guaranteed that later elements in
the array have higher addresses). If you want the
number of bytes then you have to either multiply by
the size of a double or cast the addresses of the
array elements to char before subtracting them.
When instead of doing that on elements of an array
on addresses of unrelated objects then the results
could actually be different, but there's nothing which
would tell you which one is correct or to be expected -
the compiler writer can pick whatever behaviour (s)he
considers appropriate. It would also be "correct" when
the result would always be 42.
> I understand I made the error of expanding my knowledge
> of 'micro-controllers' C compilers to the 'PC' C compilers.
> Some things won't work at all, and if they do
> it's even worse because it's just luck.
You may indeed have gotten used to a "dialect" of C (or
certain ways those compilers handle things not defined
by the standard) and you may have to unlearn a few things
you are taking for granted. Bin there, done that and
sweared quite a bit along the way;-) And it's sometimes
quite hard to grasp why certain constructs aren't well
defined by the standard, especially when one comes from
an assembler background and for quite a number of things
there is an "obvious" way in which one would assumes they
should be dealt with. There's a long list of things that
are either unspecified, undefined or implementation defined
at the end of the C99 standard (Annex J). It's not an easy
read but can help a bit getting an idea what one should
avoid when trying to write portable programs.
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
[toc] | [prev] | [next] | [standalone]
| From | Jean-Christophe <5.d@free.fr> |
|---|---|
| Date | 2012-06-02 06:47 -0700 |
| Message-ID | <0e159ddf-1c62-4bc2-bb70-a8369dec0c00@a16g2000vby.googlegroups.com> |
| In reply to | #21675 |
On 2 juin, 15:35, j...@toerring.de (Jens Thoms Toerring) wrote:
> > int i;
> > double d1, d2;
> > i = (int)( &d2 - &d1 ); // assuming &d2 > &d1
> > then i == sizeof(double) // number of bytes
> > because it's a difference of addresses
> > whatever the variable type is.
> I don't agree (...)
Yes, sorry about that.
What I had in mind was this :
#include <stdio.h>
double a,b;
int main(void)
{
unsigned int ia = (unsigned int)&a;
unsigned int ib = (unsigned int)&b;
printf( "ib - ia = %u\r\n", ib - ia );
printf( "ia - ib = %u\r\n", ia - ib );
return 0;
}
Output :
ib - ia = 8 // = sizeof(double)
ia - ib = 4294967288 // 0xFFFFFFF8
> When instead of doing that on elements of an array
> on addresses of unrelated objects then the results
> could actually be different, but there's nothing which
> would tell you which one is correct or to be expected -
> the compiler writer can pick whatever behaviour (s)he
> considers appropriate. It would also be "correct" when
> the result would always be 42.
I got that !
(Douglas Noel Adams, uh ?)
> You may indeed have gotten used to a "dialect" of C (or
> certain ways those compilers handle things not defined
> by the standard) and you may have to unlearn a few things
> you are taking for granted. Bin there, done that and
> sweared quite a bit along the way;-) And it's sometimes
> quite hard to grasp why certain constructs aren't well
> defined by the standard, especially when one comes from
> an assembler background
That's it : I'm an electronician.
> and for quite a number of things
> there is an "obvious" way in which one would assumes they
> should be dealt with. There's a long list of things that
> are either unspecified, undefined or implementation defined
> at the end of the C99 standard (Annex J). It's not an easy
> read but can help a bit getting an idea what one should
> avoid when trying to write portable programs.
Thanks again, Jens.
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-06-02 15:08 +0100 |
| Message-ID | <jqd6od$6s7$1@dont-email.me> |
| In reply to | #21676 |
"Jean-Christophe" <5.d@free.fr> wrote in message
news:0e159ddf-1c62-4bc2-bb70-a8369dec0c00@a16g2000vby.googlegroups.com...
> On 2 juin, 15:35, j...@toerring.de (Jens Thoms Toerring) wrote:
>
>> > int i;
>> > double d1, d2;
>> > i = (int)( &d2 - &d1 ); // assuming &d2 > &d1
>> > then i == sizeof(double) // number of bytes
>> > because it's a difference of addresses
>> > whatever the variable type is.
>
>> I don't agree (...)
>
> Yes, sorry about that.
> What I had in mind was this :
>
>#include <stdio.h>
>double a,b;
>int main(void)
>{
> unsigned int ia = (unsigned int)&a;
> unsigned int ib = (unsigned int)&b;
> printf( "ib - ia = %u\r\n", ib - ia );
> printf( "ia - ib = %u\r\n", ia - ib );
> return 0;
>}
(char* can be used in place of unsigned int here.)
> Output :
> ib - ia = 8 // = sizeof(double)
> ia - ib = 4294967288 // 0xFFFFFFF8
The trouble is code like this:
double a;
char x;
double b;
On a machine which doesn't need to align doubles, it's quite possible that
(char*)&a - (char*)&b might be 9 bytes. (I don't know what C would do with
&a-&b in that case; possibly divide the 9 bytes by 8 to get 1, the answer
you expect.)
You might try this:
#include <stdio.h>
double a;
char x,y,z;
double b;
int main(void)
{
printf( "&a = %u\n", (unsigned int)&a);
printf( "&b = %u\n", (unsigned int)&b);
printf( "&x = %u\n", (unsigned int)&x);
printf( "&y = %u\n", (unsigned int)&y);
printf( "&z = %u\n", (unsigned int)&z);
return 0;
}
You'll probably find the addresses are all mixed up.
Even when *all* variables are doubles, you won't know which have the lowest
and highest addresses.
--
Bartc
[toc] | [prev] | [next] | [standalone]
| From | Jean-Christophe <5.d@free.fr> |
|---|---|
| Date | 2012-06-02 07:37 -0700 |
| Message-ID | <7ff937d6-bd95-4235-9378-06f92d6f6d40@fr28g2000vbb.googlegroups.com> |
| In reply to | #21684 |
On Jun 2, 4:08 pm, "BartC" :
> #include <stdio.h>
> double a;
> char x,y,z;
> double b;
> int main(void)
> { printf( "&a = %u\n", (unsigned int)&a);
> printf( "&b = %u\n", (unsigned int)&b);
> printf( "&x = %u\n", (unsigned int)&x);
> printf( "&y = %u\n", (unsigned int)&y);
> printf( "&z = %u\n", (unsigned int)&z);
> return 0;
> }
Output :
&a = 4221624
&b = 4221632
&x = 4221640
&y = 4221641
&z = 4221642
> You'll probably find the addresses are all mixed up.
> Even when *all* variables are doubles, you won't know
> which have the lowest and highest addresses.
:o)
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-06-02 16:17 +0100 |
| Message-ID | <jqdaq0$v02$1@dont-email.me> |
| In reply to | #21687 |
"Jean-Christophe" <5.d@free.fr> wrote in message news:7ff937d6-bd95-4235-9378-06f92d6f6d40@fr28g2000vbb.googlegroups.com... > On Jun 2, 4:08 pm, "BartC" : > Output : > > &a = 4221624 > &b = 4221632 > &x = 4221640 > &y = 4221641 > &z = 4221642 I tried it on four x86-32 compilers, and get the following (I've added an extra term to highlight the differences): &a = 4202528 0 &b = 4202544 16 &x = 4202552 -4 &y = 4202540 -12 &z = 4202536 -4 &a = 4214968 0 &b = 4214984 16 &x = 4214992 -7 &y = 4214977 -15 &z = 4214976 -1 &a = 4244000 0 &b = 4244008 8 &x = 4245044 1037 &y = 4245045 1 &z = 4245046 1 &a = 4231444 0 &b = 4231452 8 &x = 4231464 8 &y = 4231460 -4 &z = 4231468 8 The following was from a non-C compiler (although it's possible that some C compiler could return this too): &a = 1638040 0 &b = 1638028 -12 &x = 1638039 11 &y = 1638038 -1 &z = 1638037 -1 >> You'll probably find the addresses are all mixed up. >> Even when *all* variables are doubles, you won't know >> which have the lowest and highest addresses. > > :o) While in the C examples, 'a' had the lower address, I don't see how this can guaranteed (and you might expect it to have higher address, if allocated first and the stack frame growing downwards). And in general you can't know what order variables might be allocated in (perhaps in declaration order, perhaps in alphabetical order, but it can be anything). Or some might not exist in memory at all. -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-06-02 19:02 +0100 |
| Message-ID | <jqdkga$qnb$1@dont-email.me> |
| In reply to | #21690 |
"BartC" <bc@freeuk.com> wrote in message news:jqdaq0$v02$1@dont-email.me... > "Jean-Christophe" <5.d@free.fr> wrote in message > news:7ff937d6-bd95-4235-9378-06f92d6f6d40@fr28g2000vbb.googlegroups.com... >> On Jun 2, 4:08 pm, "BartC" : > >> Output : >> >> &a = 4221624 >> &b = 4221632 > I tried it on four x86-32 compilers, and get the following (I've added an > extra term to highlight the differences): <Snip differences of +16, +16, +8, +8 between &a and &b (static)> >>> You'll probably find the addresses are all mixed up. >>> Even when *all* variables are doubles, you won't know >>> which have the lowest and highest addresses. > While in the C examples, 'a' had the lower address, I don't see how this > can > guaranteed (and you might expect it to have higher address, if allocated > first and the stack frame growing downwards). Jens' reply reminds me that, for some reason, your test was on static variables. Rerunning the test on local variables, then generally a had the higher address. That's with just two doubles. Declaring doubles a,b,c,d,e (with other variables interspersed), and displaying the difference between &d and &b, I was getting results of +8, -16 and +16 over four compilers. -- Bartc
[toc] | [prev] | [next] | [standalone]
Page 1 of 4 [1] 2 3 4 Next page →
Back to top | Article view | comp.lang.c
csiph-web