#define ARR_SIZE sizeof(arr)/sizeof(arr[0])

Discussion in 'C Programming' started by Vinu, May 11, 2005.

  1. Vinu

    Vinu Guest

    The following code doesn't prints anything why it is?
    The code is correct. plz explain the logic

    #include <stdio.h>

    int arr[] = {10,20,30,40,50};

    #define ARR_SIZE sizeof(arr)/sizeof(arr[0])

    void main()
    {
    for(int i= -1; i < (ARR_SIZE-1); )
    printf("Hello %d\n", arr[++i]);
    }
    Thanks & Regards
    Vinu
     
    Vinu, May 11, 2005
    #1
    1. Advertising

  2. Vinu

    Richard Bos Guest

    "Vinu" <> wrote:

    > The following code doesn't prints anything why it is?
    > The code is correct.


    The code you showed is not correct, in at least two aspects; and neither
    is asking for homework answers on Usenet.

    HTH; HAND.

    Richard
     
    Richard Bos, May 11, 2005
    #2
    1. Advertising

  3. Vinu

    S.Tobias Guest

    Vinu <> wrote:

    > for(int i= -1; i < (ARR_SIZE-1); )


    Hint: Usual Arithmetic Conversions.

    --
    Stan Tobias
    mailx `echo LID | sed s/[[:upper:]]//g`
     
    S.Tobias, May 11, 2005
    #3
  4. Vinu

    baumann@pan Guest

    see the Expert C ProgramIng , deep C secretes for the answer.
     
    baumann@pan, May 11, 2005
    #4
  5. Vinu

    Jaspreet Guest

    > > for(int i= -1; i < (ARR_SIZE-1); )
    Just remember to always compare unsigned values with a macro value.
    Basically you need to initialize i to 0. Soo, I would have main as:

    int main()
    {
    int i;
    for(i= 0; i < ARR_SIZE; )
    printf("Hello %d\n", arr[i++]);
    return(0);
    }

    Also ensure that main has a int return type. The return value should be
    a constant SUCCESS defined in one of the standard headers.
     
    Jaspreet, May 11, 2005
    #5
  6. Vinu wrote:

    > The following code doesn't prints anything why it is?
    > The code is correct. plz explain the logic
    >
    > #include <stdio.h>
    >
    > int arr[] = {10,20,30,40,50};
    >
    > #define ARR_SIZE sizeof(arr)/sizeof(arr[0])
    >
    > void main()


    int main(void)

    > {
    > for(int i= -1; i < (ARR_SIZE-1); )


    ARR_SIZE has type size_t, which is an unsigned integer type (presumably at
    least unsigned int). According to the Usual Arithmetic Conversions, i is
    converted to this unsigned type, whereby -1 becomes the maximum value for
    that type, which is definitely bigger than 4. As a result, the loop body is
    not entered at all.
    Of course, whoever wrote this code knew all that and simply wanted to
    present an example -- nobody in their right mind would write an actual for
    loop in this way.

    > printf("Hello %d\n", arr[++i]);
    > }



    Christian
     
    Christian Kandeler, May 11, 2005
    #6
  7. Vinu

    Richard Bos Guest

    "baumann@pan" <> wrote:

    > see the Expert C ProgramIng , deep C secretes for the answer.


    The answer to _what_? For heavens' sake, man, if you must use Google
    Groups Broken Beta, do learn to get it to at least quote a bit of what
    you're replying to. This way, you're more or less talking in a vacuum.

    BTW, for someone who cannot discover the OP's problem on his own, I'd
    hardly recommend Deep C Secrets. It is an altogether too confusticating
    book for someone who doesn't already know C reasonably well.

    Richard
     
    Richard Bos, May 11, 2005
    #7
  8. Vinu

    Guest

    The operator sizeof returns an unsigned value and the unsigned division
    results in unsigned value for ARR_SIZE and that results in unsigned
    comparison inside the for statement.

    So for the int i = -1; the unsigned comparison for the statement i <
    ARR_SIZE becomes as:
    0xFFFFFFFF < (5-1)

    which results in false and the printf statement inside for loop never
    gets executed and that is why you are not seeing any output!

    (I am assuming that int size is 32-bit on your system.)

    Try
    #define ARR_SIZE (int)(sizeof(arr)/sizeof(arr[0]))

    and the result will be the same as you desired.

    I hope it helps.
     
    , May 11, 2005
    #8
  9. Vinu

    baumann@pan Guest

    i think below may help u understand why .
    6.3.1 Arithmetic operands
    6.3.1.1 Boolean, characters, and integers
    1 Every integer type has an integer conversion rank defined as follows:
    - No two signed integer types shall have the same rank, even if they
    hav e the same
    representation.
    - The rank of a signed integer type shall be greater than the rank of
    any signed integer
    type with less precision.
    - The rank of long long int shall be greater than the rank of long
    int, which
    shall be greater than the rank of int, which shall be greater than the
    rank of short
    int, which shall be greater than the rank of signed char.
    - The rank of any unsigned integer type shall equal the rank of the
    corresponding
    signed integer type, if any.
    - The rank of any standard integer type shall be greater than the
    rank of any extended
    integer type with the same width.
    - The rank of char shall equal the rank of signed char and unsigned
    char.
    - The rank of _Bool shall be less than the rank of all other standard
    integer types.
    - The rank of any enumerated type shall equal the rank of the
    compatible integer type
    (see 6.7.2.2).
    - The rank of any extended signed integer type relative to another
    extended signed
    integer type with the same precision is implementation-defined, but
    still subject to the
    other rules for determining the integer conversion rank.
    - For all integer types T1, T2, and T3, if T1 has greater rank than
    T2 and T2 has
    greater rank than T3, then T1 has greater rank than T3.
    2 The following may be used in an expression wherever an int or
    unsigned int may
    be used:
    42 Language §6.3.1.1
    ©ISO/IEC ISO/IEC 9899:1999 (E)
    - An object or expression with an integer type whose integer
    conversion rank is less
    than the rank of int and unsigned int.
    - A bit-field of type _Bool, int, signed int, or unsigned int.
    If an int can represent all values of the original type, the value is
    converted to an int;
    otherwise, it is converted to an unsigned int. These are called the
    integer
    promotions.48) All other types are unchanged by the integer promotions.
    3 The integer promotions preserve value including sign. As discussed
    earlier, whether a
    ''plain'' char is treated as signed is implementation-defined.
    Forward references: enumeration specifiers (6.7.2.2), structure and
    union specifiers
    (6.7.2.1).
     
    baumann@pan, May 11, 2005
    #9
  10. Vinu

    CBFalconer Guest

    Vinu wrote:
    >
    > The following code doesn't prints anything why it is?
    > The code is correct. plz explain the logic
    >
    > #include <stdio.h>
    >
    > int arr[] = {10,20,30,40,50};
    > #define ARR_SIZE sizeof(arr)/sizeof(arr[0])
    > void main()
    > {
    > for(int i= -1; i < (ARR_SIZE-1); )
    > printf("Hello %d\n", arr[++i]);
    > }


    No, the code isn't correct. Besides problems with arithmetic
    conversions it requires a C99 system to compile (declaration of i),
    and invokes undefined behavior by failing to return a value. A
    corrected version follows, which works:

    #include <stdio.h>
    int arr[] = {10,20,30,40,50};
    #define ARR_SIZE sizeof(arr)/sizeof(arr[0])

    int main(void)
    {
    int i;

    for (i = 0; i < (ARR_SIZE); )
    printf("Hello %d\n", arr[i++]);
    return 0;
    }

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, May 11, 2005
    #10
  11. CBFalconer <> writes:
    > Vinu wrote:

    [...]
    >> #include <stdio.h>
    >>
    >> int arr[] = {10,20,30,40,50};
    >> #define ARR_SIZE sizeof(arr)/sizeof(arr[0])
    >> void main()
    >> {
    >> for(int i= -1; i < (ARR_SIZE-1); )
    >> printf("Hello %d\n", arr[++i]);
    >> }

    >
    > No, the code isn't correct. Besides problems with arithmetic
    > conversions it requires a C99 system to compile (declaration of i),
    > and invokes undefined behavior by failing to return a value.

    [...]

    No, it invokes undefined behavior by declaring void main(). If that's
    corrected to int main() or int main(void), failing to return a value
    doesn't invoke undefined behavior. In C90, it returns an unspecified
    status to the environment. In C99, unfortunately, it does an implicit
    "return 0;".

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, May 11, 2005
    #11
  12. On Wed, 11 May 2005 00:48:31 -0700, Jaspreet wrote:

    >> > for(int i= -1; i < (ARR_SIZE-1); )

    > Just remember to always compare unsigned values with a macro value.


    ?

    > Basically you need to initialize i to 0. Soo, I would have main as:
    >
    > int main()
    > {
    > int i;
    > for(i= 0; i < ARR_SIZE; )


    It would be more natural to put the i++ here then you have a normal
    iteration loop.

    > printf("Hello %d\n", arr[i++]);
    > return(0);
    > }
    >
    > Also ensure that main has a int return type. The return value should be
    > a constant SUCCESS defined in one of the standard headers.


    The portable values are 0, EXIT_SUCCESS and EXIT_FAILURE, the last 2 being
    defined in <stdlib.h>

    Lawrence
     
    Lawrence Kirby, May 12, 2005
    #12
  13. Vinu

    HalcyonWild Guest

    Vinu,

    sizeof operator returns you size_t, basically an unsigned int, you can
    assume. When you compare an int with an unsigned int ( that is , i <
    (ARR_SIZE - 1), it may give unexpected results. (Probably because, the
    16th bit is the sign bit in int datatype)

    If you typecast , it will work .. like this.
    for(int i= -1; i < (int)(ARR_SIZE-1); )

    Thanks.
     
    HalcyonWild, May 12, 2005
    #13
  14. On Thu, 12 May 2005 07:20:42 -0700, HalcyonWild wrote:

    > Vinu,
    >
    > sizeof operator returns you size_t, basically an unsigned int, you can
    > assume.


    size_t can be any unsigned integer type. As long as the integer promotions
    leave it as an unsigned int or unsigned long the problem encountered here
    will happen.

    > When you compare an int with an unsigned int ( that is , i <
    > (ARR_SIZE - 1), it may give unexpected results. (Probably because, the
    > 16th bit is the sign bit in int datatype)


    It is not to do with the sign bit specifically, it is to do with the value
    you get when you convert an int to an unsigned type. The rule is that you
    add or subtract 1 more than the maximum value that the unsigned type can
    represent until you get a value that the unsigned type can represent. So
    to convert -1 to unsigned int (assuming that type for size_t) you would
    add (UINT_MAX+1) to -1 producing the result UINT_MAX which will be greater
    than ARR_SIZE-1.

    > If you typecast , it will work .. like this.
    > for(int i= -1; i < (int)(ARR_SIZE-1); )


    Or rearrange things to avoid negative values.

    Lawrence
     
    Lawrence Kirby, May 12, 2005
    #14
    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. yogeshmk

    char *arr[n] Vs. char **arr

    yogeshmk, Jul 17, 2006, in forum: C Programming
    Replies:
    10
    Views:
    505
    deepak
    Jul 18, 2006
  2. Replies:
    5
    Views:
    504
    Old Wolf
    Jun 10, 2007
  3. Hill Pang

    What's the value of pointer arr?

    Hill Pang, Jul 3, 2011, in forum: C Programming
    Replies:
    9
    Views:
    365
    Tim Rentsch
    Jul 4, 2011
  4. F. Da Costa
    Replies:
    4
    Views:
    112
    Thomas 'PointedEars' Lahn
    Feb 16, 2004
  5. John Reye
    Replies:
    5
    Views:
    312
    Tim Rentsch
    May 31, 2012
Loading...

Share This Page