Is this type of char array initization legal?

Discussion in 'C++' started by DomoChan@gmail.com, Oct 24, 2008.

  1. Guest

    the code below will compile in visual c++ 2003, but im not sure its
    valid.

    unsigned char myString[200] = "";

    after this line executes, all the bytes within myString are indeed set
    to '0's' but is this really valid c++ or c? where can I find out how
    this is implemented?

    Im concerned because I had a 3rd party library wrapper which was
    crashing, and I was able to alleviate the crash by changing the
    initialization method from the above to ...

    unsigned char myString[200];

    memset( myString, 0, sizeof( myString ) );

    any guidance is greatly appreciated!
    -Velik
    , Oct 24, 2008
    #1
    1. Advertising

  2. wrote:
    > the code below will compile in visual c++ 2003, but im not sure its
    > valid.
    >
    > unsigned char myString[200] = "";
    >
    > after this line executes, all the bytes within myString are indeed set
    > to '0's' but is this really valid c++ or c? where can I find out how
    > this is implemented?
    >
    > Im concerned because I had a 3rd party library wrapper which was
    > crashing, and I was able to alleviate the crash by changing the
    > initialization method from the above to ...
    >
    > unsigned char myString[200];
    >
    > memset( myString, 0, sizeof( myString ) );
    >
    > any guidance is greatly appreciated!


    Practical advice: change it to

    unsigned char myString[ 200 ] = {} ;

    What to you mean by "alleviate" the crash?

    PS: the language lawyering behind the first initialization is a
    bit more complicated than I have time to explain; consider that
    the array elements are of type unsigned char (not char) and that
    there was a C standard clarification in this area which C++
    hasn't picked up (though your C++ compiler might de-facto
    implement it).

    <http://groups.google.com/group/comp.lang.c++/msg/d5ac14fbe55de25b>

    --
    Gennaro Prota | name.surname yahoo.com
    Breeze C++ (preview): <https://sourceforge.net/projects/breeze/>
    Do you need expertise in C++? I'm available.
    Gennaro Prota, Oct 24, 2008
    #2
    1. Advertising

  3. Salt_Peter Guest

    On Oct 24, 12:22 pm, wrote:
    > the code below will compile in visual c++ 2003, but im not sure its
    > valid.
    >
    > unsigned char myString[200] = "";
    >
    > after this line executes, all the bytes within myString are indeed set
    > to '0's'  but is this really valid c++ or c?  where can I find out how
    > this is implemented?


    Sounds like you see the results of a program in debug mode. The string
    literal "" is actually {'\0'} so everything after myString[0] has an
    undeterminate value. Nobody cares whether some compiler initializes or
    not the rest of the array with some magic value, there is no
    requirement that says it must.

    >
    > Im concerned because I had a 3rd party library wrapper which was
    > crashing, and I was able to alleviate the crash by changing the
    > initialization method from the above to ...
    >
    > unsigned char myString[200];
    >
    > memset( myString, 0, sizeof( myString ) );
    >
    > any guidance is greatly appreciated!
    > -Velik


    An array has a special initializer that looks like so:
    unsigned char myString[200] = {'a'};
    which initializes all elements with 'a' in this case.
    Note the element type of the array (unsigned char) and the type in the
    array init list.
    Now having said that, the above is an array, not a terminated sequence
    of unsigned characters.

    Another reason to prefer modern containers:

    #include <vector>

    // all elements initialized: guarenteed
    std::vector< unsigned char > vuc(200);

    // all 'a'
    std::vector< unsigned char > vuca(200, 'a');
    Salt_Peter, Oct 24, 2008
    #3
  4. Default User Guest

    Pete Becker wrote:

    > On 2008-10-24 12:49:25 -0400, Victor Bazarov
    > <> said:


    > > The only reason it could be crashing is if the compiler wastn't
    > > providing proper initialisation for the array. What you could do
    > > is revert this to what it was and put an assertion to see if it's
    > > indeed the problem:
    > >
    > > unsigned char myString[200] = "";
    > > #ifndef NDEBUG
    > > for (int iii = 0; iii < 200; ++iii)
    > > ASSERT(myString[iii] == 0);
    > > #endif

    >
    > Hmm, is this required if the char array has automatic storage
    > duration? I have always assumed that it wasn't, that only the
    > characters corresponding to characters in the initializer would be
    > initialized, but it doesn't seem completely clear from a quick glance
    > at the standard.


    Interesting. I also didn't find anything explicit regarding string
    literals, just the usual "fewer initializer" rule:

    If there are fewer initializers in the list than there are
    members in the aggregate, then each member not explicitly
    initialized shall be value-initialized (8.5).

    The C standard does contain such wording (assuming that it didn't
    change from the draft standard):

    [#21] If there are fewer initializers in a brace-enclosed
    list than there are elements or members of an aggregate, or
    fewer characters in a string literal used to initialize an
    array of known size than there are elements in the array,
    the remainder of the aggregate shall be initialized
    implicitly the same as objects that have static storage
    duration.

    C89's wording was similar to the C++ standard, but had further examples
    to show that initialization with a string literal is identical to a
    brace-enclosed list of the characters, which would amount to the same
    thing.




    Brian
    Default User, Oct 24, 2008
    #4
  5. Default User Guest

    Victor Bazarov wrote:

    > Pete Becker wrote:
    > >On 2008-10-24 12:49:25 -0400, Victor Bazarov


    > > Hmm, is this required if the char array has automatic storage
    > > duration? I have always assumed that it wasn't, that only the
    > > characters corresponding to characters in the initializer would be
    > > initialized, but it doesn't seem completely clear from a quick
    > > glance at the standard.
    > >

    >
    > 8.5.1/7:
    > <<If there are fewer initializers in the list than there are members
    > in the aggregate, then each member not explicitly initialized shall
    > be value-initialized (8.5).>>
    >
    > To me it's pretty clear. Each character from the literal initialises
    > its respective element of the array. The terminating null character
    > does initialise the corresponding element of the array too. If there
    > are fewer characters in the literal than elements in the array (which
    > is an aggregate), the rest of the array elements are zero-initialised.


    I'm sure it was intended, and it's always been that way in C, but
    there's some haziness. A string literal isn't a list, exactly. As I
    pointed out in another reply, the C99 standard added wording to make
    that explicit, and the older standard had wording that confirmed that a
    string literal was the same as a character list for intialization
    purposes.

    In my experience, a C++ compiler that didn't zero out the rest of the
    array would be unusual. The OP can certainly check to see if that's the
    problem.





    Brian
    Default User, Oct 24, 2008
    #5
  6. James Kanze Guest

    On Oct 24, 10:46 pm, Pete Becker <>
    wrote:
    > On 2008-10-24 16:18:56 -0400, Victor Bazarov
    > <> said:
    > > 8.5.1/7:
    > > <<If there are fewer initializers in the list than there are members in
    > > the aggregate, then each member not
    > > explicitly initialized shall be value-initialized (8.5).>>


    > Well, yes, that's the requirement for aggregate
    > initialization. But does aggregate initialization apply here?
    > Aggregate initialization is indicated by "a brace-enclosed,
    > comma-separated list ...", which isn't present here. I don't
    > see anything in 8.5.2 [dcl.init.string] that says that
    > aggregate initialization is used, although the "optionally
    > enclosed in braces" hints that it may be.


    Well, I rather think it was intended, although you do have a
    point. Probably a defect in the standard. (Maybe I should
    raise an issue. I'd love to say that it was just editorial, and
    just push it off on you, but I think it's a little too much for
    that.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Oct 24, 2008
    #6
  7. Default User Guest

    Pete Becker wrote:

    > On 2008-10-24 16:29:45 -0400, "Default User"
    > <> said:


    > > C89's wording was similar to the C++ standard, but had further
    > > examples to show that initialization with a string literal is
    > > identical to a brace-enclosed list of the characters, which would
    > > amount to the same thing.
    > >

    >
    > So C99 made it crystal clear, presumably because C90 wasn't. <g>


    It was, I think, clear enough. It just wasn't all put together nicely.
    They had examples to show that:

    char str[] = "XYZ";

    Was equivalent to:

    char str[] = {'X', 'Y', 'Z', '\0'};

    So if a string literal is equivalent to a brace-enclosed list of
    characters, then the "fewer initializer" rule would come into play to
    finish out an array larger than the string literal with '\0'.




    Brian
    Default User, Oct 24, 2008
    #7
  8. Default User Guest

    Pete Becker wrote:

    > Examples in standards are not normative. That is, they do not impose
    > requirements. They illustrate what the words say. If the words don't
    > say it, examples don't make it true.


    The question is whether the words do say it or not. The examples
    certainly help clarify the situation. On the other hand, adding
    explicit wording to the next standard indicates that not everyone was
    so convinced.





    Brian
    Default User, Oct 24, 2008
    #8
  9. Default User Guest

    Pete Becker wrote:

    > On 2008-10-24 17:53:48 -0400, "Default User"
    > <> said:
    >
    > > Pete Becker wrote:
    > >
    > > > Examples in standards are not normative. That is, they do not
    > > > impose requirements. They illustrate what the words say. If the
    > > > words don't say it, examples don't make it true.

    > >
    > > The question is whether the words do say it or not. The examples
    > > certainly help clarify the situation.

    >
    > No. Pretend the examples aren't there. What do the words say? If they
    > don't impose some particular requirement, then it's not a
    > requirement, even if examples imply that it is.


    The question is, does the requirement for filling out an array when
    there is fewer elements in the initializer list than there are in the
    declarared array apply when the initializer is a string literal? It
    doesn't specifically say that it does, but is it a legitimate
    interpretation?

    Searching back in comp.std.c, I find that apparently this issue was
    submitted as a Defect Report / Technical Corrigendum that "clarifies
    that a string literal is equivalent to a brace-enclosed
    list of characters."

    So the issue has come up before there, and that report is probably why
    C99 explicitly said so.

    It should be noted that the C++ standard does refer to the individual
    characters of a string literal as "initializers". Whether that's
    sufficient or not is hard to say.

    I don't have time right now to search comp.std.c++ (I'm off to the
    hockey game).



    Brian
    Default User, Oct 25, 2008
    #9
  10. James Kanze Guest

    On Oct 24, 11:46 pm, Pete Becker <> wrote:
    > On 2008-10-24 17:17:10 -0400, "Default User" <> said:
    > > Pete Becker wrote:


    > >> On 2008-10-24 16:29:45 -0400, "Default User"
    > >> <> said:


    > >>> C89's wording was similar to the C++ standard, but had
    > >>> further examples to show that initialization with a string
    > >>> literal is identical to a brace-enclosed list of the
    > >>> characters, which would amount to the same thing.


    > >> So C99 made it crystal clear, presumably because C90 wasn't. <g>


    > > It was, I think, clear enough. It just wasn't all put
    > > together nicely. They had examples to show that:


    > >    char str[] = "XYZ";


    > > Was equivalent to:


    > >    char str[] = {'X', 'Y', 'Z', '\0'};


    > > So if a string literal is equivalent to a brace-enclosed
    > > list of characters, then the "fewer initializer" rule would
    > > come into play to finish out an array larger than the string
    > > literal with '\0'.


    > Examples in standards are not normative. That is, they do not
    > impose requirements. They illustrate what the words say. If
    > the words don't say it, examples don't make it true.


    In this case, the words do say what the example shows. But it
    has nothing to do with the case at hand, something like:
    char str[ 20 ] = "abc" ;
    Is this guaranteed to initialize all 20 bytes, or just the first
    four?

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Oct 25, 2008
    #10
  11. Default User Guest

    Pete Becker wrote:

    > On 2008-10-24 19:21:26 -0400, "Default User"
    > <> said:
    >
    > >
    > > Searching back in comp.std.c, I find that apparently this issue was
    > > submitted as a Defect Report / Technical Corrigendum that "clarifies
    > > that a string literal is equivalent to a brace-enclosed
    > > list of characters."
    > >
    > > So the issue has come up before there, and that report is probably
    > > why C99 explicitly said so.

    >
    > Sigh. That's what I said several messages back. C99 changed the
    > wording because the C90 words weren't clear.


    You mentioned nothing about this defect report. My research was to add
    to the previous discussion, not to refute anything.




    Brian

    --
    If televison's a babysitter, the Internet is a drunk librarian who
    won't shut up.
    -- Dorothy Gambrell (http://catandgirl.com)
    Default User, Oct 25, 2008
    #11
  12. James Kanze Guest

    On Oct 24, 10:47 pm, Pete Becker <> wrote:
    > On 2008-10-24 17:11:10 -0400, James Kanze <> said:
    > > On Oct 24, 10:46 pm, Pete Becker <>
    > > wrote:
    > >> On 2008-10-24 16:18:56 -0400, Victor Bazarov
    > >> <> said:
    > >>> 8.5.1/7:
    > >>> <<If there are fewer initializers in the list than there are members in
    > >>> the aggregate, then each member not
    > >>> explicitly initialized shall be value-initialized (8.5).>>


    > >> Well, yes, that's the requirement for aggregate
    > >> initialization. But does aggregate initialization apply
    > >> here? Aggregate initialization is indicated by "a
    > >> brace-enclosed, comma-separated list ...", which isn't
    > >> present here. I don't see anything in 8.5.2
    > >> [dcl.init.string] that says that aggregate initialization
    > >> is used, although the "optionally enclosed in braces" hints
    > >> that it may be.


    > > Well, I rather think it was intended, although you do have a
    > > point.  Probably a defect in the standard.  (Maybe I should
    > > raise an issue.  I'd love to say that it was just editorial,
    > > and just push it off on you, but I think it's a little too
    > > much for that.)


    > Me, too. <g>


    Done. I've raised the issue with the committee.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Oct 26, 2008
    #12
    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. wwj
    Replies:
    7
    Views:
    538
  2. lovecreatesbeauty
    Replies:
    1
    Views:
    1,007
    Ian Collins
    May 9, 2006
  3. Replies:
    3
    Views:
    720
  4. davidb
    Replies:
    0
    Views:
    752
    davidb
    Sep 1, 2006
  5. davidb
    Replies:
    6
    Views:
    1,533
    Default User
    Sep 1, 2006
Loading...

Share This Page