Q: Local variables initialization shortcut.

Discussion in 'C Programming' started by Jean-Christophe, Jun 2, 2012.

  1. 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.
     
    Jean-Christophe, Jun 2, 2012
    #1
    1. Advertising

  2. Jean-Christophe

    jacob navia Guest

    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

    :)
     
    jacob navia, Jun 2, 2012
    #2
    1. Advertising

  3. Jean-Christophe

    Ian Collins Guest

    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
     
    Ian Collins, Jun 2, 2012
    #3
  4. 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 !
     
    Jean-Christophe, Jun 2, 2012
    #4
  5. 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'.
     
    Jean-Christophe, Jun 2, 2012
    #5
  6. Jean-Christophe <> 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 ___
    \__________________________ http://toerring.de
     
    Jens Thoms Toerring, Jun 2, 2012
    #6
  7. Jean-Christophe

    BartC Guest

    "Jean-Christophe" <> wrote in message
    news:...

    > 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) ) );
    >
    > ...
    > }


    You need a feature not available in C, which is being able to have a
    variable which is an alias of another. It might work like this:

    double V[26]={0};
    double a @ V[0], b @ V[1], etc.

    Then identifier 'c' is equivalant to 'V[2]'. This way you might expect the
    26-element V array to be cleared more efficiently than 26 individual
    variables.

    The nearest C can actually do might be:

    #define a (V[0])
    #define b (V[1])
    etc

    But, these macro names will have file scope; they will no longer be local.
    (Unless maybe you play around with #undef and stuff like that.) Of course
    your actual variable names might not be single letters so it need not be an
    issue.

    You can also use array elements directly: V[0], V[1] in place of a,b. Or
    define some enumerations:

    enum {a,b,c...} so that it's possible to write V[a], V etc.

    Alternatively, a struct can be used to contain all the variables:

    struct {double a, b, c,... }V = {0};

    Now you can just write: V.a, V.b and so on.

    It's possible also that your compiler will arrange the variables so that it
    can initialise them as one block anyway...

    --
    bartc
     
    BartC, Jun 2, 2012
    #7
  8. On 2 juin, 12:31, :

    > 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.
     
    Jean-Christophe, Jun 2, 2012
    #8
  9. On 2 juin, 12:45, "BartC" :

    > You need a feature not available in C, which is being able to have a
    > variable which is an alias of another. It might work like this:
    > double V[26]={0};
    > double a @ V[0], b @ V[1], etc.
    > Then identifier 'c' is equivalant to 'V[2]'. This way you might expect the
    > 26-element V array to be cleared more efficiently than 26 individual
    > variables.


    Yep.


    > The nearest C can actually do might be:
    > #define a (V[0])
    > #define b (V[1])
    > etc


    Yes, that's what I said to 'Jens'.
    But to write the whole set of #define will be a pain.
    ( some functions have as much as ~50 variables ... )


    > But, these macro names will have file scope; they will no longer be local.
    > (Unless maybe you play around with #undef and stuff like that.)


    Yes, in this case that's what I would have done.
    ( just at the end '}' of the function)


    > Of course your actual variable names might not be single letters


    No, they are not single letters.


    > so it need not be an issue.
    > You can also use array elements directly: V[0], V[1] in place of a,b. Or
    > define some enumerations:
    > enum {a,b,c...} so that it's possible to write V[a], V etc.


    Yes, but then, using variables in the code will look like :

    V[VAR_THIS] = ... ;

    Which I found less easy-to-use and trensparent than :

    VAR_THIS = ... ;


    > Alternatively, a struct can be used to contain all the variables:
    > struct {double a, b, c,... }V = {0};
    > Now you can just write: V.a, V.b and so on.


    Yes, I think it's the easyest shortcut in this case.

    Now the drawback is : many functions with always-different
    variable names, meaning a lot of different structures to define.


    > It's possible also that your compiler will arrange the variables
    > so that it can initialise them as one block anyway...


    Yes, but I can't seriously rely on this since these
    are local allocations in stack, done at runtime, etc.

    I'm translating an existing source code into C language so
    I'm using the very same variables names (to ease debugging)
    I *have* to keep separate, 'individual', variables names.
    (if I wrote it down in the fist place, I'd use structures)
     
    Jean-Christophe, Jun 2, 2012
    #9
  10. Jean-Christophe

    BartC Guest

    "Jean-Christophe" <> wrote in message
    news:...
    > On 2 juin, 12:45, "BartC" :
    >
    >> You need a feature not available in C, which is being able to have a
    >> variable which is an alias of another. It might work like this:
    >> double V[26]={0};
    >> double a @ V[0], b @ V[1], etc.
    >> Then identifier 'c' is equivalant to 'V[2]'. This way you might expect
    >> the
    >> 26-element V array to be cleared more efficiently than 26 individual
    >> variables.

    >
    > Yep.


    Actually, if you are using doubles, then it doesn't necessarily follow that
    it will be much slower to clear these one-by-one, compared with, say, 8 or
    16-bit variables. (It's possible also it might be faster, if the compiler
    would otherwise use a loop.) Have you done any measurements?

    > I'm translating an existing source code into C language so
    > I'm using the very same variables names (to ease debugging)
    > I *have* to keep separate, 'individual', variables names.
    > (if I wrote it down in the fist place, I'd use structures)


    Do the variables need to be cleared on every call to the function? If they
    only need to be cleared once, then using static variables will ensure they
    are 0.0 at the start of execution (at least, on most hardware).

    Also, does *every* variable need to start at zero? Some, surely, must have a
    different starting value, perhaps set by an assignment. (In which case, a
    compiler might optimise out the 0.0 initialisation; but it means you don't
    need to clear it first.)

    You mentioned Windows elsewhere. If you're only interested in one particular
    platform (eg. x86) and don't care about portability, perhaps consider a bit
    of inline assembler. This can look at the frame and stack pointers, and do a
    block clear of the memory in between. Although this will indiscriminately
    zero all local variables, including ones you want initialised to something
    else. (They need initialising by assignment instead.)

    --
    Bartc
     
    BartC, Jun 2, 2012
    #10
  11. Jean-Christophe

    BartC Guest

    "BartC" <> wrote in message news:jqcu41$oa0$...
    > "Jean-Christophe" <> wrote in message


    >> I'm translating an existing source code into C language so


    > You mentioned Windows elsewhere. If you're only interested in one
    > particular
    > platform (eg. x86) and don't care about portability, perhaps consider a
    > bit
    > of inline assembler. This can look at the frame and stack pointers, and do
    > a block clear of the memory in between.


    I should add this might not be portable across compilers either. Especially
    gcc, which might just decide to eliminate the frame pointer completely. But
    then it also makes it more difficult to use inline asm anyway.

    --
    Bartc
     
    BartC, Jun 2, 2012
    #11
  12. Jean-Christophe <> wrote:
    > On 2 juin, 12:31, :
    > > 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 ___
    \__________________________ http://toerring.de
     
    Jens Thoms Toerring, Jun 2, 2012
    #12
  13. On 2 juin, 13:40, "BartC" :

    > Actually, if you are using doubles, then it doesn't necessarily follow that
    > it will be much slower to clear these one-by-one, compared with, say, 8 or
    > 16-bit variables. (It's possible also it might be faster, if the compiler
    > would otherwise use a loop.) Have you done any measurements?


    The speed is not an issue here.
    The point is to reset to zero all these variables,
    while keeping their original names.


    > Do the variables need to be cleared on every call to the function?


    Yes.


    > If they only need to be cleared once, then using static variables
    > will ensure they are 0.0 at the start of execution
    > (at least, on most hardware).


    Nah, can't be static.


    > Also, does *every* variable need to start at zero?
    > Some, surely, must have a different starting value,
    > perhaps set by an assignment.


    Yes.


    > (In which case, a compiler might optimise out the 0.0
    > initialisation; but it means you don't need to clear it first.)


    That's right, but the original code is a real mess,
    for debug purpose I need al least to set all variables to zero
    otherwise I won't even know whose values are (in)correct.


    > You mentioned Windows elsewhere. If you're only interested in one particular
    > platform (eg. x86) and don't care about portability,


    Yes, this is the case.


    > perhaps consider a bit of inline assembler.
    > This can look at the frame and stack pointers, and do a
    > block clear of the memory in between. Although this will indiscriminately
    > zero all local variables, including ones you want initialised to something
    > else. (They need initialising by assignment instead.)


    Hum, sounds a bit tricky to me.
    Thanks for the idea anyway.
     
    Jean-Christophe, Jun 2, 2012
    #13
  14. On 2 juin, 14:03, pete :

    > If you beieve that something which works once,
    > will always work again,


    I didn't meant that.

    > then why ask questions
    > instead of just testing your code?


    Because I need advice.

    > The C standard characterizes that operation as being undefined.
    > N1570
    > 6.5.6 Additive operators
    > 9 When two pointers are subtracted,
    > both shall point to elements of the same array object,
    > or one past the last element of the array object;
    > the result is the difference of the
    > subscripts of the two array elements.


    Good enough for me, thanks.
     
    Jean-Christophe, Jun 2, 2012
    #14
  15. On 2 juin, 13:55, (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.
     
    Jean-Christophe, Jun 2, 2012
    #15
  16. Jean-Christophe

    Eric Sosman Guest

    On 6/2/2012 7:55 AM, Jens Thoms Toerring wrote:
    > Jean-Christophe<> wrote:
    >> [...]
    >>> '&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.


    As a concrete example not requiring "exotic" hardware,
    consider this fragment:

    char buff[15];
    typedef char Blob[7];
    Blob *b1 = (Blob*) &buff[0];
    Blob* b2 = (Blob*) &buff[8];

    Now, what is `b2 - b1'? Pointer subtraction is supposed to
    yield the number of pointed-at things between the two positions,
    but how many 7-byte Blobs fit in the 8 bytes between their
    starting positions? (For extra credit, change `8' to `1' in
    the final line and answer again.)

    In other words, the requirement is even stronger than Jens'
    informal statement of it: You can only subtract pointers within
    an array *of the pointed-at type*. The fact that `b1' and `b2'
    both aim at spots within the array `buff' is not enough.

    --
    Eric Sosman
    d
     
    Eric Sosman, Jun 2, 2012
    #16
  17. My apologies :

    #include <stdio.h>
    int main(void)
    {
    double a,b;
    printf( "&b - &a = %2d\r\n", (int)( &b - &a ) );
    printf( "&a - &b = %2d\r\n", (int)( &a - &b ) );
    return 0;
    }

    &b - &a = 1
    &a - &b = -1
     
    Jean-Christophe, Jun 2, 2012
    #17
  18. Sorry about the misunderstanding,
    this is what I meant :

    #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;
    }


    ib - ia = 8 // = sizeof(double)
    ia - ib = 4294967288 // crap
     
    Jean-Christophe, Jun 2, 2012
    #18
  19. Jean-Christophe

    BartC Guest

    "Jean-Christophe" <> wrote in message
    news:...
    > On 2 juin, 13:40, "BartC" :
    >
    >> Actually, if you are using doubles, then it doesn't necessarily follow
    >> that
    >> it will be much slower to clear these one-by-one, compared with, say, 8
    >> or
    >> 16-bit variables. (It's possible also it might be faster, if the compiler
    >> would otherwise use a loop.) Have you done any measurements?

    >
    > The speed is not an issue here.
    > The point is to reset to zero all these variables,
    > while keeping their original names.


    Perhaps I'm missing the point somewhere, but in that case, what's wrong
    with:

    double a=0.0, b=0.0, .... ?

    Do you just want to save some typing?

    > perhaps consider a bit of inline assembler.
    >> This can look at the frame and stack pointers, and do a
    >> block clear of the memory in between.


    > Hum, sounds a bit tricky to me.
    > Thanks for the idea anyway.


    Yeah, forget that. You need to be on intimate terms with your compiler to
    try things like that.

    --
    Bartc
     
    BartC, Jun 2, 2012
    #19
  20. On 2 juin, 15:00, "BartC" :

    > Perhaps I'm missing the point somewhere,
    > but in that case, what's wrong with:
    > double a=0.0, b=0.0, .... ?
    > Do you just want to save some typing?


    I'm re-writing a messy 7500 lines source code into C,
    I kept all the same variables names to ease debugging
    and there are a LOT of functions, each one with its
    own LOT of local variables - all having different names.
    At least I want to initialise all of them to zero to
    avoid uninitialized variables ****-up (if I may say so)

    So it won't save me 'some' typing: I'll save a 'lot' of typing.


    > > perhaps consider a bit of inline assembler.
    > >> This can look at the frame and stack pointers, and do a
    > >> block clear of the memory in between.

    > > Hum, sounds a bit tricky to me.
    > > Thanks for the idea anyway.


    > Yeah, forget that. You need to be on intimate
    > terms with your compiler to try things like that.


    Sure. Thanks Bartc.
     
    Jean-Christophe, Jun 2, 2012
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Pekka Niiranen
    Replies:
    1
    Views:
    330
    Alex Martelli
    Nov 6, 2004
  2. Andrew
    Replies:
    5
    Views:
    404
    Leif K-Brooks
    Jun 19, 2005
  3. Michal Kwiatkowski

    Local variables initialization

    Michal Kwiatkowski, Feb 26, 2006, in forum: Python
    Replies:
    5
    Views:
    332
    Michal Kwiatkowski
    Feb 27, 2006
  4. auspicious
    Replies:
    0
    Views:
    325
    auspicious
    Sep 25, 2008
  5. Severin Ecker
    Replies:
    9
    Views:
    735
    James Kanze
    Mar 11, 2010
Loading...

Share This Page