Find the size of an array

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • arnuld

    Find the size of an array

    I want to create a new array of the same size of an array already
    available:


    #include <stdio.h>
    #include <string.h>

    int main(void)
    {
    char arrc[] = "URI";
    const int asize = sizeof(arrc) / sizeof (arrc[0]);
    char new_arr[asize];

    printf("new_arr size = %d\n", sizeof(new_arr) );

    return 0;
    }

    =============== ========= OUTPUT =============== =====
    [arnuld@dune C]$ gcc4 -ansi -pedantic -Wall -Wextra test.c
    test.c: In function ‘main’:
    test.c:9: warning: ISO C90 forbids variable-size array ‘new_arr’
    [arnuld@dune C]$ ./a.out
    new_arr size = 4
    [arnuld@dune C]$



    The program gives correct answer. But Why the warning. sizeof() is compile
    time operator then why do I get some warning related to run-time ?




    --

    my email is @ the above blog.
    Google Groups is UnBlocked now :)


  • Richard Heathfield

    #2
    Re: Find the size of an array

    arnuld said:
    I want to create a new array of the same size of an array already
    available:
    >
    >
    #include <stdio.h>
    #include <string.h>
    >
    int main(void)
    {
    char arrc[] = "URI";
    const int asize = sizeof(arrc) / sizeof (arrc[0]);
    char new_arr[asize];
    >
    printf("new_arr size = %d\n", sizeof(new_arr) );
    >
    return 0;
    }
    >
    =============== ========= OUTPUT =============== =====
    [arnuld@dune C]$ gcc4 -ansi -pedantic -Wall -Wextra test.c
    test.c: In function ?main?:
    test.c:9: warning: ISO C90 forbids variable-size array ?new_arr?
    [arnuld@dune C]$ ./a.out
    new_arr size = 4
    [arnuld@dune C]$
    >
    The program gives correct answer. But Why the warning. sizeof() is
    compile time operator then why do I get some warning related to run-time
    ?
    gcc is being a little terse here (for understandable reasons). Yes,
    sizeof's result is evaluated by the compiler. But, by the time the
    compiler is looking at new_arr, it's forgotten all about the sizeof in the
    previous line. All it can see is that you've got this asize thing, which
    is a const int *but NOT an integral constant expression* - a puzzling
    distinction, but a very real one in C.

    You can get what you want, however, by cutting out the middle-man:

    char arrc[] = "URI";
    char new_arr[sizeof arrc / sizeof arrc[0]];

    --
    Richard Heathfield <http://www.cpax.org.uk >
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999

    Comment

    • Keith Thompson

      #3
      Re: Find the size of an array

      Michael <michael@michae ldadmum.no-ip.orgwrites:
      arnuld wrote:
      >I want to create a new array of the same size of an array already
      >available:
      >#include <stdio.h>
      >#include <string.h>
      >int main(void)
      >{
      > char arrc[] = "URI";
      > const int asize = sizeof(arrc) / sizeof (arrc[0]);
      > char new_arr[asize];
      > printf("new_arr size = %d\n", sizeof(new_arr) );
      > return 0;
      >}
      >============== ========== OUTPUT =============== =====
      >[arnuld@dune C]$ gcc4 -ansi -pedantic -Wall -Wextra test.c
      >test.c: In function ¡main¢:
      >test.c:9: warning: ISO C90 forbids variable-size array ¡new_arr¢
      >[arnuld@dune C]$ ./a.out new_arr size = 4
      >[arnuld@dune C]$ The program gives correct answer. But Why the
      >warning. sizeof() is compile
      >time operator then why do I get some warning related to run-time ?
      I have a warning on line 10. Use %lu instead of %d solves it.
      It solves it only if size_t happens to be a typedef for unsigned long.
      For C90, the portable solution is to use "%lu" *and* convert the
      sizeof expression to unsigned long:

      printf("new_arr size = %lu\n", (unsigned long)sizeof new_arr);
      There is
      no problems elsewhere.
      As I think has already been mentioned in this thread, asize is not a
      constant expression, so it can't be used as an array size in C90. In
      C99, new_arr is a VLA (variable-length array). A solution to this
      that's portable to both C90 and C99 has already been posted: use
      "sizeof arrc / sizeof arrc[0]" directly as the array size.

      --
      Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
      Nokia
      "We must do something. This is something. Therefore, we must do this."
      -- Antony Jay and Jonathan Lynn, "Yes Minister"

      Comment

      • arnuld

        #4
        Re: Find the size of an array

        On Thu, 06 Nov 2008 06:54:12 +0000, Richard Heathfield wrote:

        gcc is being a little terse here (for understandable reasons). Yes,
        sizeof's result is evaluated by the compiler. But, by the time the
        compiler is looking at new_arr, it's forgotten all about the sizeof in the
        previous line. All it can see is that you've got this asize thing, which
        is a const int *but NOT an integral constant expression* - a puzzling
        distinction, but a very real one in C.
        Now what is the difference between a "const int" and an "inegeral constant
        expression". I can't seem to understand it. May I have 2 examples
        showing the distinction, so that I can comprehend something out of them.


        You can get what you want, however, by cutting out the middle-man:
        char arrc[] = "URI";
        char new_arr[sizeof arrc / sizeof arrc[0]];

        That works fine. Now the real problem is to understand the confusing
        distinction.



        --

        my email is @ the above blog.


        Comment

        • Richard Heathfield

          #5
          Re: Find the size of an array

          arnuld said:
          >On Thu, 06 Nov 2008 06:54:12 +0000, Richard Heathfield wrote:
          >
          >
          >gcc is being a little terse here (for understandable reasons). Yes,
          >sizeof's result is evaluated by the compiler. But, by the time the
          >compiler is looking at new_arr, it's forgotten all about the sizeof in
          >the previous line. All it can see is that you've got this asize thing,
          >which is a const int *but NOT an integral constant expression* - a
          >puzzling distinction, but a very real one in C.
          >
          Now what is the difference between a "const int" and an "inegeral
          constant expression". I can't seem to understand it. May I have 2
          examples showing the distinction, so that I can comprehend something out
          of them.
          A const int is simply an int that you've promised not to change, by
          "decorating " it with the word "const".

          On the other hand, "integral constant expression" is a formal term that is
          relevant to a number of aspects of C programming, amongst them the number
          of elements specified in an array (or, in the case of C99, a non-VL array)
          at the time of its declaration.

          So - what characteristics does an integral constant expression have? "An
          integral constant expression shall have integral type and shall only have
          operands that are integer constants, enumeration constants, character
          constants, sizeof expressions, and floating constants that are the
          immediate operands of casts."

          Examples of integer constants: 0, 6, 42
          Examples of character constants: 'A', 'z', '.'
          Example of sizeof expression: sizeof otherarray / sizeof otherarray[0]
          Example of floating constants that are the immediate operands of casts:
          (int)3.14159

          --
          Richard Heathfield <http://www.cpax.org.uk >
          Email: -http://www. +rjh@
          Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
          "Usenet is a strange place" - dmr 29 July 1999

          Comment

          • Gordon Burditt

            #6
            Re: Find the size of an array

            >Now what is the difference between a "const int" and an "inegeral constant
            >expression".
            A const int is "const" but not "ant". That is, it's not a compile-time
            constant. Why? Because the standard says so. Generally, anything
            that requires accessing memory is not a compile-time constant, even
            something like "Hello"[0], which should be equal to 'H'.

            An "integral constant expression" is constant (including at
            compile-time), by definition.

            const int not_constant = 42;

            switch(c)
            {
            case 42: /* allowed */
            break;
            case not_constant: /* not allowed */
            break;
            }
            >I can't seem to understand it. May I have 2 examples
            >showing the distinction, so that I can comprehend something out of them.
            Note that "const" means more that "YOU cannot write it" not "NOBODY
            can write it". This is a perfectly logical declaration:

            extern const volatile time_t hardware_real_t ime_clock;

            although how you define the variable requires something outside
            Standard C if the variable name is descriptive of what it actually
            is. It changes by itself with time. YOU may not set it.

            Comment

            • arnuld

              #7
              Re: Find the size of an array

              On Fri, 07 Nov 2008 07:09:26 +0000, Richard Heathfield wrote:
              A const int is simply an int that you've promised not to change, by
              "decorating " it with the word "const".

              So compiler can change it, I can not ?

              On the other hand, "integral constant expression" is a formal term that is
              relevant to a number of aspects of C programming, amongst them the number
              of elements specified in an array (or, in the case of C99, a non-VL array)
              at the time of its declaration.
              So - what characteristics does an integral constant expression have? "An
              integral constant expression shall have integral type and shall only have
              operands that are integer constants, enumeration constants, character
              constants, sizeof expressions, and floating constants that are the
              immediate operands of casts."
              Examples of integer constants: 0, 6, 42
              Examples of character constants: 'A', 'z', '.'
              Example of sizeof expression: sizeof otherarray / sizeof otherarray[0]
              Example of floating constants that are the immediate operands of casts:
              (int)3.14159

              Therefore array depends on an "integral constant expression" not a
              constant integer. IOW, should I stop using const and start using enum for
              a real constant ?



              --

              my email is @ the above blog.


              Comment

              • Ian Collins

                #8
                Re: Find the size of an array

                arnuld wrote:
                >
                Therefore array depends on an "integral constant expression" not a
                constant integer. IOW, should I stop using const and start using enum for
                a real constant ?
                >
                Due to the broken nature of const in C, yes if you want a compile time
                constant.

                const is fine when an integral constant expression is not required.

                --
                Ian Collins

                Comment

                • Keith Thompson

                  #9
                  Re: Find the size of an array

                  arnuld <sunrise@invali d.addresswrites :
                  >On Thu, 06 Nov 2008 06:54:12 +0000, Richard Heathfield wrote:
                  >gcc is being a little terse here (for understandable reasons). Yes,
                  >sizeof's result is evaluated by the compiler. But, by the time the
                  >compiler is looking at new_arr, it's forgotten all about the sizeof in the
                  >previous line. All it can see is that you've got this asize thing, which
                  >is a const int *but NOT an integral constant expression* - a puzzling
                  >distinction, but a very real one in C.
                  >
                  Now what is the difference between a "const int" and an "inegeral constant
                  expression". I can't seem to understand it. May I have 2 examples
                  showing the distinction, so that I can comprehend something out of them.
                  The tricky thing is that "const" does *not* mean "constant" -- or
                  rather "const" doesn't mean what C means by "constant". And yes, it's
                  a poor choice of words, but we're stuck with it, even though the word
                  "const" obviously is derived from the English word "constant".

                  "const" really means "read-only". If an object is declared "const",
                  then attempting to modify it is a constraint violation.

                  "constant", as in "constant expression", means roughly that the
                  expression can be evaluated at compile time. I say "roughly" because
                  that's not how the standard defines it; the standard restricts the
                  kinds of things that can appear in a constant expression. All
                  constant expressions can be evaluated at compile time, but not all
                  expressions that can be evaluated at compile time (by a sufficiently
                  clever compiler) are "constant expressions". Basically, the language
                  doesn't require the compiler to be *too* clever.

                  For example, this is perfectly legal:

                  const int r = rand();
                  const time_t start_time = time(NULL);

                  In both cases the initial value can't be computed until run time; the
                  "const" says that you're not allowed to modify the object once it's
                  been initialized. (You can *attempt* do modify it via a tricky
                  pointer cast, but that's undefined behavior.)

                  And here's another example where "const" is definitely not constant:

                  int var = 42;
                  const int *ptr = &var; /* pointer to const int */
                  var = 43; /* perfectly legal */
                  *ptr = 44; /* bzzzt! *ptr is const; you're not allowed
                  to change it */

                  Here the object has two "names", var and *ptr. The object itself
                  isn't read-only, but one of its two "names" is read-only. (The
                  standard doesn't use the word "name" this way, thus the quotation
                  marks.)

                  Another way to look at it: applying "const" to something asks the
                  compiler to complain if you attempt to modify it.

                  Now if I declare
                  const int x = 100;

                  then the compiler is certainly free to evaluate x at compile time,
                  replacing any reference to x with a literal 100. That's just a matter
                  of optimization; it doesn't change the visible behavior of the
                  program. What the compiler *can't* do is allow you to use "x" in a
                  context that requires a constant expression -- such as (in C90) an
                  array length.

                  (And yes, I'm using the word "allow" a bit loosely here; compilers can
                  permit such things, but you can't depend on it.)

                  --
                  Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                  Nokia
                  "We must do something. This is something. Therefore, we must do this."
                  -- Antony Jay and Jonathan Lynn, "Yes Minister"

                  Comment

                  • Michael

                    #10
                    Re: Find the size of an array

                    arnuld wrote:
                    I want to create a new array of the same size of an array already
                    available:
                    >
                    >
                    #include <stdio.h>
                    #include <string.h>
                    >
                    int main(void)
                    {
                    char arrc[] = "URI";
                    const int asize = sizeof(arrc) / sizeof (arrc[0]);
                    char new_arr[asize];
                    >
                    printf("new_arr size = %d\n", sizeof(new_arr) );
                    >
                    return 0;
                    }
                    >
                    =============== ========= OUTPUT =============== =====
                    [arnuld@dune C]$ gcc4 -ansi -pedantic -Wall -Wextra test.c
                    test.c: In function ‘main’:
                    test.c:9: warning: ISO C90 forbids variable-size array ‘new_arr’
                    [arnuld@dune C]$ ./a.out
                    new_arr size = 4
                    [arnuld@dune C]$
                    >
                    >
                    >
                    The program gives correct answer. But Why the warning. sizeof() is compile
                    time operator then why do I get some warning related to run-time ?
                    >
                    >
                    >
                    >
                    I have a warning on line 10. Use %lu instead of %d solves it. There is
                    no problems elsewhere.

                    Comment

                    • Phil Carmody

                      #11
                      Re: Find the size of an array

                      Ian Collins <ian-news@hotmail.co mwrites:
                      arnuld wrote:
                      >>
                      >Therefore array depends on an "integral constant expression" not a
                      >constant integer. IOW, should I stop using const and start using enum for
                      >a real constant ?
                      >
                      Due to the broken nature of const in C, yes if you want a compile time
                      constant.
                      Is it broken? I find for driver work that const volatile ints do
                      precisely what I want in C, and don't even let me try to do anything
                      that I wouldn't want.
                      const is fine when an integral constant expression is not required.
                      And haircuts are fine when lunch isn't required. Different beasties,
                      horses for courses, and stuff.

                      Phil
                      --
                      We must respect the other fellow's religion, but only in the sense and to the
                      extent that we respect his theory that his wife is beautiful and his children
                      smart. -- Henry Louis Mencken (1880-1956), American editor and critic

                      Comment

                      • Ian Collins

                        #12
                        Re: Find the size of an array

                        Phil Carmody wrote:
                        Ian Collins <ian-news@hotmail.co mwrites:
                        >arnuld wrote:
                        >>Therefore array depends on an "integral constant expression" not a
                        >>constant integer. IOW, should I stop using const and start using enum for
                        >>a real constant ?
                        >Due to the broken nature of const in C, yes if you want a compile time
                        >constant.
                        >
                        Is it broken? I find for driver work that const volatile ints do
                        precisely what I want in C, and don't even let me try to do anything
                        that I wouldn't want.
                        >
                        const volatile is the exception.

                        There isn't any good reason why a const integral type can't be a compile
                        time constant. The only reason I can think of is oversight.

                        --
                        Ian Collins

                        Comment

                        • Barry Schwarz

                          #13
                          Re: Find the size of an array

                          On Sat, 08 Nov 2008 00:20:11 +1300, Ian Collins <ian-news@hotmail.co m>
                          wrote:
                          >Phil Carmody wrote:
                          >Ian Collins <ian-news@hotmail.co mwrites:
                          >>arnuld wrote:
                          >>>Therefore array depends on an "integral constant expression" not a
                          >>>constant integer. IOW, should I stop using const and start using enum for
                          >>>a real constant ?
                          >>Due to the broken nature of const in C, yes if you want a compile time
                          >>constant.
                          >>
                          >Is it broken? I find for driver work that const volatile ints do
                          >precisely what I want in C, and don't even let me try to do anything
                          >that I wouldn't want.
                          >>
                          >const volatile is the exception.
                          >
                          >There isn't any good reason why a const integral type can't be a compile
                          >time constant. The only reason I can think of is oversight.
                          At least one problem is it requires the compiler to keep track of the
                          value of variable. While expressions like sizeof A / sizeof *A are
                          computable at compile time, there is no requirement to do so. And
                          what happens with
                          const int x = func();

                          --
                          Remove del for email

                          Comment

                          • Phil Carmody

                            #14
                            Re: Find the size of an array

                            Ian Collins <ian-news@hotmail.co mwrites:
                            Phil Carmody wrote:
                            >Ian Collins <ian-news@hotmail.co mwrites:
                            >>arnuld wrote:
                            >>>Therefore array depends on an "integral constant expression" not a
                            >>>constant integer. IOW, should I stop using const and start using enum for
                            >>>a real constant ?
                            >>Due to the broken nature of const in C, yes if you want a compile time
                            >>constant.
                            >>
                            >Is it broken? I find for driver work that const volatile ints do
                            >precisely what I want in C, and don't even let me try to do anything
                            >that I wouldn't want.
                            >
                            const volatile is the exception.
                            >
                            There isn't any good reason why a const integral type can't be a compile
                            time constant. The only reason I can think of is oversight.
                            Not all const ints, surely? I'm not sure anyone's called
                            for:

                            unsigned int foo(const unsigned int bar)
                            {
                            struct { unsigned int baz : bar; } a; // BANG!
                            a.baz=bar;
                            return a.baz;
                            }

                            (Then again, s/: bar/: ' '/ for an apparently legal horror.)


                            I'd vote for things "ABC"[1] being a compile-time constant with
                            the same value as 'B', though.

                            Phil
                            --
                            We must respect the other fellow's religion, but only in the sense and to the
                            extent that we respect his theory that his wife is beautiful and his children
                            smart. -- Henry Louis Mencken (1880-1956), American editor and critic

                            Comment

                            • Ben Bacarisse

                              #15
                              Re: Find the size of an array

                              Ian Collins <ian-news@hotmail.co mwrites:
                              Phil Carmody wrote:
                              >Ian Collins <ian-news@hotmail.co mwrites:
                              >>arnuld wrote:
                              >>>Therefore array depends on an "integral constant expression" not a
                              >>>constant integer. IOW, should I stop using const and start using enum for
                              >>>a real constant ?
                              >>Due to the broken nature of const in C, yes if you want a compile time
                              >>constant.
                              >>
                              >Is it broken? I find for driver work that const volatile ints do
                              >precisely what I want in C, and don't even let me try to do anything
                              >that I wouldn't want.
                              >>
                              const volatile is the exception.
                              >
                              There isn't any good reason why a const integral type can't be a compile
                              time constant.
                              How can it be one?

                              void f(const int x)
                              {
                              int a[x];
                              /* ... */
                              }

                              What you mean is probably more like "why can't a const-qualified
                              integer object, initialised with a constant expression, be used in
                              constant expressions?".
                              The only reason I can think of is oversight.
                              I think that is a very unlikely explanation. Personally, I prefer the
                              C++ definition but I don't think that was formalised in 1989 when C
                              got const as a keyword. I can't imagine that the C++ semantics were
                              not considered by the C99 committee but I hesitate to suggest why they
                              was rejected.

                              --
                              Ben.

                              Comment

                              Working...