Question about the clc string lib

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

    Question about the clc string lib

    In the function below, can size ever be 0 (zero)?

    char *clc_strdup(con st char * CLC_RESTRICT s)
    {
    size_t size;
    char *p;

    clc_assert_not_ null(clc_strdup , s);

    size = strlen(s) + 1;
    if (size == 0)
    p = NULL;
    else if ((p = malloc(size)) != NULL)
    memcpy(p, s, size);

    return p;
    }

  • Jordan Abel

    #2
    Re: Question about the clc string lib

    On 2006-01-26, Jeff <joesiege@gmail .com> wrote:[color=blue]
    > In the function below, can size ever be 0 (zero)?[/color]

    I've never heard of the "clc string lib" - where can i find it?
    [color=blue]
    > char *clc_strdup(con st char * CLC_RESTRICT s)
    > {
    > size_t size;
    > char *p;
    >
    > clc_assert_not_ null(clc_strdup , s);[/color]

    No idea how this would work in a way that needs the function pointer as
    its first argument. Is it a macro that stringizes its first argument to
    print an error?
    [color=blue]
    >
    > size = strlen(s) + 1;[/color]

    The result of this assignment cannot be zero.
    [color=blue]
    > if (size == 0)
    > p = NULL;[/color]

    hold on - i take that back. size can be 0 if strlen returns SIZE_MAX.
    [color=blue]
    > else if ((p = malloc(size)) != NULL)
    > memcpy(p, s, size);
    >
    > return p;
    >}[/color]

    Incidentally, speaking of prefixes, the str* prefix, and reserved
    identifiers, is something along the lines of

    #define strdup clc_strdup

    legal? My reading of the standard says it is, but thought i'd ask here.

    Comment

    • pemo

      #3
      Re: Question about the clc string lib

      Jeff wrote:[color=blue]
      > In the function below, can size ever be 0 (zero)?
      >
      > char *clc_strdup(con st char * CLC_RESTRICT s)
      > {
      > size_t size;
      > char *p;
      >
      > clc_assert_not_ null(clc_strdup , s);
      >
      > size = strlen(s) + 1;
      > if (size == 0)
      > p = NULL;
      > else if ((p = malloc(size)) != NULL)
      > memcpy(p, s, size);
      >
      > return p;
      > }[/color]

      If s is a null terminated string, even if s[0] == '\0', then strlen of s
      will be 0. As you add one to that, in this case, size cannot be 0.

      if s is of such a length that it overflows a size_t (on my system that's
      SIZE_MAX = UNIT32_MAX = 4294967295 [+ 1], then size will go to 0. Again, as
      you add 1 to that, I can't see how size can ever be zero.

      --
      ==============
      *Not a pedant*
      ==============


      Comment

      • Jordan Abel

        #4
        Re: Question about the clc string lib

        On 2006-01-26, pemo <usenetmeister@ gmail.com> wrote:[color=blue]
        > Jeff wrote:[color=green]
        >> In the function below, can size ever be 0 (zero)?
        >>
        >> char *clc_strdup(con st char * CLC_RESTRICT s)
        >> {
        >> size_t size;
        >> char *p;
        >>
        >> clc_assert_not_ null(clc_strdup , s);
        >>
        >> size = strlen(s) + 1;
        >> if (size == 0)
        >> p = NULL;
        >> else if ((p = malloc(size)) != NULL)
        >> memcpy(p, s, size);
        >>
        >> return p;
        >> }[/color]
        >
        > If s is a null terminated string, even if s[0] == '\0', then strlen of s
        > will be 0. As you add one to that, in this case, size cannot be 0.
        >
        > if s is of such a length that it overflows a size_t (on my system that's
        > SIZE_MAX = UNIT32_MAX = 4294967295 [+ 1], then size will go to 0. Again, as
        > you add 1 to that, I can't see how size can ever be zero.[/color]

        Except, if the length of s _is_ SIZE_MAX, then subsequently adding 1
        will "overflow".

        suppose we have an unrealistic system where SIZE_MAX is 63. [clearly not
        ISO compliant, but i don't want to type out 65535 characters]

        then, the string
        "abcdefghijklmn opqrstuvwxyzABC DEFGHIJKLMNOPQR STUVWXYZ 0123456789"

        has a length of 63, and 63+1 will wrap to 0.

        Comment

        • pemo

          #5
          Re: Question about the clc string lib

          Jordan Abel wrote:[color=blue]
          > On 2006-01-26, pemo <usenetmeister@ gmail.com> wrote:[color=green]
          >> Jeff wrote:[color=darkred]
          >>> In the function below, can size ever be 0 (zero)?
          >>>
          >>> char *clc_strdup(con st char * CLC_RESTRICT s)
          >>> {
          >>> size_t size;
          >>> char *p;
          >>>
          >>> clc_assert_not_ null(clc_strdup , s);
          >>>
          >>> size = strlen(s) + 1;
          >>> if (size == 0)
          >>> p = NULL;
          >>> else if ((p = malloc(size)) != NULL)
          >>> memcpy(p, s, size);
          >>>
          >>> return p;
          >>> }[/color]
          >>
          >> If s is a null terminated string, even if s[0] == '\0', then strlen
          >> of s will be 0. As you add one to that, in this case, size cannot
          >> be 0.
          >>
          >> if s is of such a length that it overflows a size_t (on my system
          >> that's SIZE_MAX = UNIT32_MAX = 4294967295 [+ 1], then size will go
          >> to 0. Again, as you add 1 to that, I can't see how size can ever be
          >> zero.[/color]
          >
          > Except, if the length of s _is_ SIZE_MAX, then subsequently adding 1
          > will "overflow".
          >
          > suppose we have an unrealistic system where SIZE_MAX is 63. [clearly
          > not ISO compliant, but i don't want to type out 65535 characters]
          >
          > then, the string
          > "abcdefghijklmn opqrstuvwxyzABC DEFGHIJKLMNOPQR STUVWXYZ 0123456789"
          >
          > has a length of 63, and 63+1 will wrap to 0.[/color]

          Yup - agreed, if the string is exactly SIZE_MAX in length. Thanks for the
          correction.

          --
          ==============
          *Not a pedant*
          ==============


          Comment

          • Vladimir S. Oka

            #6
            Re: Question about the clc string lib

            Jordan Abel wrote:

            < snip OP and tidbits >
            [color=blue]
            > Incidentally, speaking of prefixes, the str* prefix, and reserved
            > identifiers, is something along the lines of
            >
            > #define strdup clc_strdup
            >
            > legal? My reading of the standard says it is, but thought i'd ask
            > here.[/color]

            I believe it is (and can't be asked to open the Standard right now).

            In any case, by the time the compiler proper sees the code, all
            instances of `strdup` will be replaced by the pre-processor with the
            `clc_strdup` which does not violate the "str[lowercaseletter] is
            reserved" requirement.

            Cheers

            Vladimir

            --
            If you make people think they're thinking, they'll love you; but if you
            really make them think they'll hate you.

            Comment

            • boa

              #7
              Re: Question about the clc string lib

              Jordan Abel wrote:[color=blue]
              > On 2006-01-26, Jeff <joesiege@gmail .com> wrote:[color=green]
              >> In the function below, can size ever be 0 (zero)?[/color]
              >
              > I've never heard of the "clc string lib" - where can i find it?[/color]

              The web page for the libclc project

              [color=blue]
              >[color=green]
              >> char *clc_strdup(con st char * CLC_RESTRICT s)
              >> {
              >> size_t size;
              >> char *p;
              >>
              >> clc_assert_not_ null(clc_strdup , s);[/color]
              >
              > No idea how this would work in a way that needs the function pointer as
              > its first argument. Is it a macro that stringizes its first argument to
              > print an error?
              >[color=green]
              >> size = strlen(s) + 1;[/color]
              >
              > The result of this assignment cannot be zero.
              >[color=green]
              >> if (size == 0)
              >> p = NULL;[/color]
              >
              > hold on - i take that back. size can be 0 if strlen returns SIZE_MAX.[/color]

              size can never be SIZE_MAX as size doesn't include '\0'. A valid string
              always has the '\0' and the max size of a buffer containing a string is
              SIZE_MAX.

              boa

              Comment

              • boa

                #8
                Re: Question about the clc string lib

                boa wrote:[color=blue]
                > Jordan Abel wrote:[color=green]
                >> On 2006-01-26, Jeff <joesiege@gmail .com> wrote:[color=darkred]
                >>> In the function below, can size ever be 0 (zero)?[/color]
                >>
                >> I've never heard of the "clc string lib" - where can i find it?[/color]
                >
                > http://libclc.sf.net
                >[color=green]
                >>[color=darkred]
                >>> char *clc_strdup(con st char * CLC_RESTRICT s)
                >>> {
                >>> size_t size;
                >>> char *p;
                >>>
                >>> clc_assert_not_ null(clc_strdup , s);[/color]
                >>
                >> No idea how this would work in a way that needs the function pointer as
                >> its first argument. Is it a macro that stringizes its first argument to
                >> print an error?
                >>[color=darkred]
                >>> size = strlen(s) + 1;[/color]
                >>
                >> The result of this assignment cannot be zero.
                >>[color=darkred]
                >>> if (size == 0)
                >>> p = NULL;[/color]
                >>
                >> hold on - i take that back. size can be 0 if strlen returns SIZE_MAX.[/color]
                >
                > size can never be SIZE_MAX as size doesn't include '\0'. A valid string
                > always has the '\0' and the max size of a buffer containing a string is
                > SIZE_MAX.
                >
                > boa[/color]

                One more try: strlen() can never return SIZE_MAX. A valid string
                always has the '\0' and the max size of a buffer containing a string is
                SIZE_MAX, so the max value strlen() can return is SIZE_MAX - 1.

                boa

                Comment

                • Jordan Abel

                  #9
                  Re: Question about the clc string lib

                  On 2006-01-26, boa <boasema@gmail. com> wrote:[color=blue]
                  > boa wrote:[color=green]
                  >> Jordan Abel wrote:[color=darkred]
                  >>> On 2006-01-26, Jeff <joesiege@gmail .com> wrote:
                  >>>> In the function below, can size ever be 0 (zero)?
                  >>>
                  >>> I've never heard of the "clc string lib" - where can i find it?[/color]
                  >>
                  >> http://libclc.sf.net
                  >>[color=darkred]
                  >>>
                  >>>> char *clc_strdup(con st char * CLC_RESTRICT s)
                  >>>> {
                  >>>> size_t size;
                  >>>> char *p;
                  >>>>
                  >>>> clc_assert_not_ null(clc_strdup , s);
                  >>>
                  >>> No idea how this would work in a way that needs the function pointer as
                  >>> its first argument. Is it a macro that stringizes its first argument to
                  >>> print an error?
                  >>>
                  >>>> size = strlen(s) + 1;
                  >>>
                  >>> The result of this assignment cannot be zero.
                  >>>
                  >>>> if (size == 0)
                  >>>> p = NULL;
                  >>>
                  >>> hold on - i take that back. size can be 0 if strlen returns SIZE_MAX.[/color]
                  >>
                  >> size can never be SIZE_MAX as size doesn't include '\0'. A valid string
                  >> always has the '\0' and the max size of a buffer containing a string is
                  >> SIZE_MAX.
                  >>
                  >> boa[/color]
                  >
                  > One more try: strlen() can never return SIZE_MAX. A valid string
                  > always has the '\0' and the max size of a buffer containing a string is
                  > SIZE_MAX, so the max value strlen() can return is SIZE_MAX - 1.
                  >
                  > boa[/color]

                  take SIZE_MAX 65535

                  char * foo = calloc(256,256) ;
                  memset(foo,"x", SIZE_MAX);
                  strlen(foo) == SIZE_MAX;

                  I don't think there's an explicit requirement in the standard that there
                  never be an object smaller than SIZE_MAX. There may, however, be a
                  requirement that the product of the arguments to calloc be less than
                  SIZE_MAX. [that, i don't know.]

                  Comment

                  • Jeff

                    #10
                    Re: Question about the clc string lib


                    Jordan Abel wrote:[color=blue]
                    > On 2006-01-26, pemo <usenetmeister@ gmail.com> wrote:[color=green]
                    > > Jeff wrote:[color=darkred]
                    > >> In the function below, can size ever be 0 (zero)?
                    > >>
                    > >> char *clc_strdup(con st char * CLC_RESTRICT s)
                    > >> {
                    > >> size_t size;
                    > >> char *p;
                    > >>
                    > >> clc_assert_not_ null(clc_strdup , s);
                    > >>
                    > >> size = strlen(s) + 1;
                    > >> if (size == 0)
                    > >> p = NULL;
                    > >> else if ((p = malloc(size)) != NULL)
                    > >> memcpy(p, s, size);
                    > >>
                    > >> return p;
                    > >> }[/color]
                    > >
                    > > If s is a null terminated string, even if s[0] == '\0', then strlen of s
                    > > will be 0. As you add one to that, in this case, size cannot be 0.
                    > >
                    > > if s is of such a length that it overflows a size_t (on my system that's
                    > > SIZE_MAX = UNIT32_MAX = 4294967295 [+ 1], then size will go to 0. Again, as
                    > > you add 1 to that, I can't see how size can ever be zero.[/color]
                    >
                    > Except, if the length of s _is_ SIZE_MAX, then subsequently adding 1
                    > will "overflow".
                    >
                    > suppose we have an unrealistic system where SIZE_MAX is 63. [clearly not
                    > ISO compliant, but i don't want to type out 65535 characters]
                    >
                    > then, the string
                    > "abcdefghijklmn opqrstuvwxyzABC DEFGHIJKLMNOPQR STUVWXYZ 0123456789"
                    >
                    > has a length of 63, and 63+1 will wrap to 0.[/color]

                    But if the most you can allocate is SIZE_MAX, then your string can only
                    be SIZE_MAX-1 if it's going to be null terminated. Therefore I don't
                    see how strlen can return SIZE_MAX.

                    Jeff

                    Comment

                    • boa

                      #11
                      Re: Question about the clc string lib

                      Jordan Abel wrote:[color=blue]
                      > On 2006-01-26, boa <boasema@gmail. com> wrote:[color=green]
                      >> boa wrote:[color=darkred]
                      >>> Jordan Abel wrote:
                      >>>> On 2006-01-26, Jeff <joesiege@gmail .com> wrote:
                      >>>>> In the function below, can size ever be 0 (zero)?
                      >>>> I've never heard of the "clc string lib" - where can i find it?
                      >>> http://libclc.sf.net
                      >>>
                      >>>>> char *clc_strdup(con st char * CLC_RESTRICT s)
                      >>>>> {
                      >>>>> size_t size;
                      >>>>> char *p;
                      >>>>>
                      >>>>> clc_assert_not_ null(clc_strdup , s);
                      >>>> No idea how this would work in a way that needs the function pointer as
                      >>>> its first argument. Is it a macro that stringizes its first argument to
                      >>>> print an error?
                      >>>>
                      >>>>> size = strlen(s) + 1;
                      >>>> The result of this assignment cannot be zero.
                      >>>>
                      >>>>> if (size == 0)
                      >>>>> p = NULL;
                      >>>> hold on - i take that back. size can be 0 if strlen returns SIZE_MAX.
                      >>> size can never be SIZE_MAX as size doesn't include '\0'. A valid string
                      >>> always has the '\0' and the max size of a buffer containing a string is
                      >>> SIZE_MAX.
                      >>>
                      >>> boa[/color]
                      >> One more try: strlen() can never return SIZE_MAX. A valid string
                      >> always has the '\0' and the max size of a buffer containing a string is
                      >> SIZE_MAX, so the max value strlen() can return is SIZE_MAX - 1.
                      >>
                      >> boa[/color]
                      >
                      > take SIZE_MAX 65535
                      >
                      > char * foo = calloc(256,256) ;
                      > memset(foo,"x", SIZE_MAX);
                      > strlen(foo) == SIZE_MAX;
                      >
                      > I don't think there's an explicit requirement in the standard that there
                      > never be an object smaller than SIZE_MAX. There may, however, be a
                      > requirement that the product of the arguments to calloc be less than
                      > SIZE_MAX. [that, i don't know.][/color]

                      It goes without saying? ;-)

                      FWIW, I've looked through both the C99 standard, the C rationale and
                      TC1, looking for some description of the relationship between size_t and
                      SIZE_MAX, but found nothing. SIZE_T is only mentioned twice in C99.

                      So I really don't have much of a case here. One could argue that even if
                      it is OK to calloc() memory the way you do above, you don't allocate a
                      string, just 256 objects of 256 bytes so you cannot use it as an
                      argument to strlen().

                      The standard is vague on this issue, 7.21.1 says this:[color=blue]
                      > The header <string.h> declares one type and several functions, and defines one
                      > macro useful for manipulating arrays of character type and other objects treated as arrays
                      > of character type.[/color]

                      Pretty clear that strlen() manipulates arrays of character type, but
                      what's "other objects"?

                      boa

                      Comment

                      • Steve Summit

                        #12
                        Re: Question about the clc string lib

                        Jordan Abel wrote:[color=blue]
                        > I've never heard of the "clc string lib" -[/color]

                        Silly me, I hadn't either!
                        [color=blue][color=green]
                        >> clc_assert_not_ null(clc_strdup , s);[/color]
                        >
                        > No idea how this would work in a way that needs the function pointer as
                        > its first argument. Is it a macro that stringizes its first argument to
                        > print an error?[/color]

                        Good question. But it could also just be used as a
                        guaranteed-unique, easy-to-produce token.

                        My suggestion, though, would be to omit that assertion entirely
                        and replace it with a simple

                        if(s == NULL)
                        return NULL;

                        Comment

                        • Keith Thompson

                          #13
                          Re: Question about the clc string lib

                          Jordan Abel <random832@gmai l.com> writes:[color=blue]
                          > On 2006-01-26, Jeff <joesiege@gmail .com> wrote:[color=green]
                          >> In the function below, can size ever be 0 (zero)?[/color]
                          >
                          > I've never heard of the "clc string lib" - where can i find it?
                          >[color=green]
                          >> char *clc_strdup(con st char * CLC_RESTRICT s)
                          >> {
                          >> size_t size;
                          >> char *p;
                          >>
                          >> clc_assert_not_ null(clc_strdup , s);[/color]
                          >
                          > No idea how this would work in a way that needs the function pointer as
                          > its first argument. Is it a macro that stringizes its first argument to
                          > print an error?[/color]

                          That's the most likely case (but then why not just pass a string?),
                          but it *could* be a function that compares its first argument against
                          the address of each function that it knows about. Silly, but
                          possible.

                          --
                          Keith Thompson (The_Other_Keit h) kst-u@mib.org <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.

                          Comment

                          • Michael Wojcik

                            #14
                            Re: Question about the clc string lib


                            In article <drb09c$hbb$1@n wrdmz01.dmz.ncs .ea.ibs-infra.bt.com>, "Vladimir S. Oka" <novine@btopenw orld.com> writes:[color=blue]
                            > Jordan Abel wrote:
                            >[color=green]
                            > > Incidentally, speaking of prefixes, the str* prefix, and reserved
                            > > identifiers, is something along the lines of
                            > >
                            > > #define strdup clc_strdup
                            > >
                            > > legal? My reading of the standard says it is, but thought i'd ask
                            > > here.[/color]
                            >
                            > I believe it is (and can't be asked to open the Standard right now).[/color]

                            If you can't be bothered to check the Standard, why reply? That's
                            a serious question. Jordan's question was about the Standard, not
                            about anyone else's belief.

                            I *am* looking at the Standard (I'll cite C99 here, but C90 has
                            equivalent, indeed mostly identical, language). My interpretation
                            of the Standard contradicts Jordan's.

                            Note first that macro names are identifiers (6.2.1).

                            7.1.3 ("Reserved identifiers"):

                            Each header declares or defines all identifiers listed in its
                            associated subclause, and optionally declares or defines identifiers
                            listed in its associated future library directions subclause and
                            identifiers which are always reserved either for any use or for use
                            as file scope identifiers.
                            ...
                            Each identifier with file scope listed in any of the following
                            subclauses (including the future library directions) is reserved for
                            use as a macro name and as an identifier with file scope in the same
                            name space if any of its associated headers is included.

                            Note the "str..." identifiers in string.h are identifiers with file
                            scope.

                            7.26.10 ("General utilities <stdlib.h>"):

                            Function names that begin with str and a lowercase letter may be
                            added to the declarations in the <stdlib.h> header.

                            7.26.11 ("String handling <string.h>"):

                            Function names that begin with str, mem, or wcs and a lowercase
                            letter may be added to the declarations in the <string.h> header.


                            "strdup" as a macro name is an identifier that begins with "str"
                            and a lowercase letter. It has file scope, because it is a macro
                            name. That means it is covered by 7.26.10 and 7.26.11. By 7.1.3,
                            it is thus reserved if stdlib.h or string.h is included.

                            The only thing that making it a macro name rather than simply having
                            a function (with external linkage) named "strdup" gives you is
                            relief from 7.26:

                            7.26 ("Future library directions"):

                            All external names described below are reserved no matter what
                            headers are included by the program.

                            So calling the function "clc_strdup " and using a macro to refer to it
                            as "strdup" is legal provided stdlib.h and string.h are not included
                            - but that seems rather unlikely, and you could achieve the same thing
                            by giving "strdup" internal linkage (ie by declaring it static).

                            [color=blue]
                            > In any case, by the time the compiler proper sees the code, all
                            > instances of `strdup` will be replaced by the pre-processor with the
                            > `clc_strdup` which does not violate the "str[lowercaseletter] is
                            > reserved" requirement.[/color]

                            This is mostly wrong. There is no "compiler proper" as far as the
                            Standard is concerned; the replacement of macro-name identifiers with
                            macro bodies is part of translation phase four, carried out by the
                            same notional "implementation " as all other translation phases. More
                            importantly, some of the restrictions on reserved identifiers, like
                            this one, apply to macro names. That the macro name is replaced with
                            its associated body is irrelevant in this case.

                            Now, Jordan certainly knows how preprocessing directives and macro
                            expansion work. His question had to do with what the Standard says
                            about reserved identifiers and whether an identifier of particular
                            type and name was reserved. This is a question which can only be
                            answered by recourse to the Standard, not by speculation about what
                            happens during compilation; it is a point of law, not a point of
                            fact. It is, in other words, a question of pedantry, and only
                            pedantry will satisfy it.

                            Fortunately, c.l.c contains one of the world's largest herds of free-
                            roaming pedants, thundering majestically across the virtual plains...


                            --
                            Michael Wojcik michael.wojcik@ microfocus.com

                            World domination has encountered a momentary setback. Talk amongst
                            yourselves. -- Darby Conley

                            Comment

                            • Keith Thompson

                              #15
                              Re: Question about the clc string lib

                              mwojcik@newsguy .com (Michael Wojcik) writes:
                              [...][color=blue]
                              > Fortunately, c.l.c contains one of the world's largest herds of free-
                              > roaming pedants, thundering majestically across the virtual plains...[/color]

                              I just wanted to quote that sentence.

                              --
                              Keith Thompson (The_Other_Keit h) kst-u@mib.org <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.

                              Comment

                              Working...