What is const char * const *p;

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Vijay Kumar R. Zanvar

    What is const char * const *p;

    Hello,

    I have few questions. They are:

    1. Is "const char * const *p;" a valid construct?
    2. How do I align a given structure, say, at 32-byte boundary?
    3. Then, how do I assert that a given object is aligned, say,
    at 32-byte boundary?


    Regards,

    --
    Vijay Kumar R. Zanvar
    Home Page - http://geocities.com/vijoeyz/
  • E. Robert Tisdale

    #2
    Re: What is const char * const *p;

    Vijay Kumar R. Zanvar wrote:
    [color=blue]
    >
    >
    > I have few questions.
    >
    > 1. Is "const char* const *p;" a valid construct?[/color]

    Yes. Both p and the char to which p ponts are const.
    [color=blue]
    > 2. How do I align a given structure, say, at 32-byte boundary?[/color]

    char* q = (char*)malloc(6 4);
    char* p = (q + 31)&(~31);

    p is aligned on a quad word boundary.

    [color=blue]
    > 3. Then, how do I assert that a given object is aligned, say,
    > at 32-byte boundary?[/color]

    assert(p == ((p + 31)&(~31)));

    Comment

    • Richard Bos

      #3
      Re: What is const char * const *p;

      vijoeyz@gmail.c om (Vijay Kumar R. Zanvar) wrote:
      [color=blue]
      > 1. Is "const char * const *p;" a valid construct?[/color]

      Yes.
      [color=blue]
      > 2. How do I align a given structure, say, at 32-byte boundary?
      > 3. Then, how do I assert that a given object is aligned, say,
      > at 32-byte boundary?[/color]

      You don't, and you can be reasonably but not perfectly sure,
      respectively.

      That is, if you happen to _know_ that a certain C type must be aligned
      on 32-byte boundaries, then you also know that both all actual objects
      of that type are indeed so aligned, and that so is the memory you get
      from malloc() (because that must be correctly aligned for any type,
      including your 32-byte one).
      The problem is finding a type like that, because nothing in the Standard
      demands anything about the alignment of any type except that several
      kinds of types must have the same alignment as closely related types
      (e.g., signed and unsigned int must be identically aligned; void * has
      the same requirements as char *; etc.) and that malloc() returns an
      all-suitable pointer. There is nothing that either demands that a
      certain type is aligned to certain boundaries, or that allows you to
      find out which alignment requirements a type has.
      Oh, one exception: because array members are contiguous, all types can
      have no stricter alignment requirements than to sizeof(type). But since
      they could also be aligned more loosely (say, to half of sizeof(type)),
      this doesn't actually help you any if you really need an alignment of a
      particular strictness. In particular, any object of type struct align {
      char align[32]; } is not guaranteed to be aligned on a 32-byte boundary,
      or indeed any boundary at all.

      As for asserting the alignment of an existing object, you can try to
      check that ((intptr_t)&obj ect)%32 (or if you use C89, ((unsigned
      long)&object)%3 2) is zero. This is not strictly required to work, since
      conversion from pointers to integers is implementation-defined, but it
      would not be unreasonable to assume that on all modern implementations ,
      this does in fact work as expected - if only because the implementor
      would have to go out of his way to make it fail. So expect it to fail
      quite spectacularly on the DS9K <g>, but not on any common system.

      Richard

      Comment

      • Charlie Gordon

        #4
        Re: What is const char * const *p;

        "E. Robert Tisdale" <E.Robert.Tisda le@jpl.nasa.gov > wrote in message
        news:coh1tp$cd8 $1@nntp1.jpl.na sa.gov...[color=blue]
        > Vijay Kumar R. Zanvar wrote a bit hastily:
        >[color=green]
        > >
        > >
        > > I have few questions.
        > >
        > > 1. Is "const char* const *p;" a valid construct?[/color]
        >
        > Yes. Both p and the char to which p ponts are const.[/color]

        No! p points to a constant pointer to constant chars. You can change p, but
        you cannot change the pointer it points to, not the characters this pointer
        points to.
        [color=blue][color=green]
        > > 2. How do I align a given structure, say, at 32-byte boundary?[/color]
        >
        > char* q = (char*)malloc(6 4);
        > char* p = (q + 31)&(~31);
        >
        > p is aligned on a quad word boundary.[/color]

        quad word ? what is the size of a word ? are you mixing bits and bytes ?
        The above code will not compile on a decently configured compiler because it
        does implicit conversions between integers and pointers. you can use this
        instead:

        unsigned char *q = malloc(32 + 31);
        void *p = (void*)(((unsig ned long)q + 31) & ~31);

        But it not portable code either. On a C99 conformant environment, you may use
        intptr_t instead of unsigned long to allow for pointers with a different size
        than long, but the arithmetic trick played is not guaranteed to have the
        required effect on pointer alignment on all architectures.
        [color=blue][color=green]
        > > 3. Then, how do I assert that a given object is aligned, say,
        > > at 32-byte boundary?[/color]
        >
        > assert(p == ((p + 31)&(~31)));[/color]

        Same remark : implicit conversions between pointer and integer.
        With the restrictions expressed above, use this:

        assert(((unsign ed long)p & 31) == 0);

        --
        Chqrlie.


        Comment

        • Chris Croughton

          #5
          Re: What is const char * const *p;

          On Mon, 29 Nov 2004 21:54:38 -0800, E. Robert Tisdale
          <E.Robert.Tisda le@jpl.nasa.gov > wrote:
          [color=blue]
          > Vijay Kumar R. Zanvar wrote:
          >[color=green]
          >> 2. How do I align a given structure, say, at 32-byte boundary?[/color]
          >
          > char* q = (char*)malloc(6 4);
          > char* p = (q + 31)&(~31);
          >
          > p is aligned on a quad word boundary.[/color]

          That is undefined behaviour in standard C:

          6.5.10 Bitwise AND operator

          Constraints
          2 Each of the operands shall have integer type

          How do you know that the (int) value (~31) is wide enough to bitwise and
          with a pointer to give meaningful results?

          In C99 you could write:

          #include <stdint.h>

          ...

          void *q = malloc(64);
          intptr_t pq = ((intptr_t)q + 31) & (~31);
          char *p = (char*)pq;

          However, although the standard guarantees that an intptr_t is a "signed
          integer type with the property that any valid pointer to void can be
          converted to this type, then converted back to pointer to void, and the
          result will compare equal to the original pointer", it does not
          guarantee that the result after doing arbitrary arithmetic operations on
          the type will still convert back to a valid pointer. For instance, a
          pointer to character could be defined on a hypothetical machine as:


          +-+-+-+-+- ... -+-+
          | b | word-ptr |
          +-+-+-+-+- ... -+-+

          Where 'word-ptr' is the pointer to a 32 bit word and 'b' an 8-bit byte
          reference within the word. Pointer arithmetic on T* would manipulate it
          appropriately (if sizeof(T) were a multiple of 4 bytes then it would be
          simple, otherwise the compiler would have to shift bits around), but
          casting to an intptr_t and anding with ~31 would produce a very wrong
          result.

          Unlikely, certainly, but nothing in the standard forbids it.
          [color=blue][color=green]
          >> 3. Then, how do I assert that a given object is aligned, say,
          >> at 32-byte boundary?[/color]
          >
          > assert(p == ((p + 31)&(~31)));[/color]

          The same applies.

          In my own code I have assumed that malloc() is standard-compliant and
          returns an area of memory which is "suitably aligned so that it may be
          assigned to a pointer to any type of object and then used to access such
          an object or an array of such objects in the space allocated" (section
          7.20.3), and then have made sure that if I subdivide it I do so in sizes
          also aligned to the worst case.

          Note that since arrays of objects are contiguous, any object need only
          be aligned to its own size (or rather the size of the biggest builtin
          type in the object if it is an aggregate) as a worst case. Unless you
          are doing some system-dependant thing which needs a special alignment
          (for instance using hardware-accessed buffers).

          Chris C

          Comment

          • Dan Pop

            #6
            Re: What is const char * const *p;

            In <slrncqolrt.gkd .chris@ccserver .keris.net> Chris Croughton <chris@keristor .net> writes:
            [color=blue]
            >On Mon, 29 Nov 2004 21:54:38 -0800, E. Robert Tisdale
            > <E.Robert.Tisda le@jpl.nasa.gov > wrote:
            >[color=green]
            >> Vijay Kumar R. Zanvar wrote:
            >>[color=darkred]
            >>> 2. How do I align a given structure, say, at 32-byte boundary?[/color]
            >>
            >> char* q = (char*)malloc(6 4);
            >> char* p = (q + 31)&(~31);
            >>
            >> p is aligned on a quad word boundary.[/color]
            >
            >That is undefined behaviour in standard C:
            >
            > 6.5.10 Bitwise AND operator
            >
            > Constraints
            > 2 Each of the operands shall have integer type[/color]

            A constraint violation is not undefined behaviour. Basically, it means
            that this is not standard C code and the compiler must diagnose it,
            while undefined behaviour need not be diagnosed.

            Dan
            --
            Dan Pop
            DESY Zeuthen, RZ group
            Email: Dan.Pop@ifh.de
            Currently looking for a job in the European Union

            Comment

            • CBFalconer

              #7
              Re: What is const char * const *p;

              "E. Robert Tisdale" wrote:[color=blue]
              > Vijay Kumar R. Zanvar wrote:
              >[/color]
              .... snip ...[color=blue]
              >[color=green]
              >> 3. Then, how do I assert that a given object is aligned, say,
              >> at 32-byte boundary?[/color]
              >
              > assert(p == ((p + 31)&(~31)));[/color]

              Undefined behaviour. This is an operation that can only be
              performed outside the C language, and is non-portable.

              --
              Chuck F (cbfalconer@yah oo.com) (cbfalconer@wor ldnet.att.net)
              Available for consulting/temporary embedded and systems.
              <http://cbfalconer.home .att.net> USE worldnet address!


              Comment

              • Dan Pop

                #8
                Re: What is const char * const *p;

                In <4201587f.04112 92137.9d4043e@p osting.google.c om> vijoeyz@gmail.c om (Vijay Kumar R. Zanvar) writes:
                [color=blue]
                >1. Is "const char * const *p;" a valid construct?[/color]

                Yes, of course.
                [color=blue]
                >2. How do I align a given structure, say, at 32-byte boundary?[/color]

                You cannot do that portably in C.
                [color=blue]
                >3. Then, how do I assert that a given object is aligned, say,
                > at 32-byte boundary?[/color]

                Ditto.

                The best you can do in C is converting pointers to (unsigned) integers,
                adjust the integers so they become multiples of the desired alignment and
                then convert them back to pointers. Alignment checking is performed the
                same way.

                Here's some sample C89 code that may or may not work (it works on all
                mainstream implementations ):

                struct struct32 { ... } *p;
                char buff[sizeof(struct struct32) + 31];
                unsigned long addr = (unsigned long)buff, tmp;

                p = (struct struct32 *) (addr + ((tmp = addr % 32) ? 32 - tmp : 0));
                if ((unsigned long)p % 32 == 0) /* p is aligned */ ;

                When the desired alignment is a power of 2, the % operator can be replaced
                by bitwise operations, but the code becomes less readable.

                Dan
                --
                Dan Pop
                DESY Zeuthen, RZ group
                Email: Dan.Pop@ifh.de
                Currently looking for a job in the European Union

                Comment

                • Dan Pop

                  #9
                  Re: What is const char * const *p;

                  In <41AC91D9.37175 CE7@yahoo.com> CBFalconer <cbfalconer@yah oo.com> writes:
                  [color=blue]
                  >"E. Robert Tisdale" wrote:[color=green]
                  >> Vijay Kumar R. Zanvar wrote:
                  >>[/color]
                  >... snip ...[color=green]
                  >>[color=darkred]
                  >>> 3. Then, how do I assert that a given object is aligned, say,
                  >>> at 32-byte boundary?[/color]
                  >>
                  >> assert(p == ((p + 31)&(~31)));[/color]
                  >
                  >Undefined behaviour.[/color]

                  Can I have the chapter and verse? I always thought it was a constraint
                  violation:

                  6.5.10 Bitwise AND operator

                  Syntax

                  1 AND-expression:
                  equality-expression
                  AND-expression & equality-expression

                  Constraints

                  2 Each of the operands shall have integer type.
                  [color=blue]
                  >This is an operation that can only be performed outside the C language,[/color]

                  Wrong again: it can be performed without violating the C language
                  specification, by converting the pointer to a suitable integer type.
                  [color=blue]
                  >and is non-portable.[/color]

                  This is correct, in theory, at least.

                  Dan
                  --
                  Dan Pop
                  DESY Zeuthen, RZ group
                  Email: Dan.Pop@ifh.de
                  Currently looking for a job in the European Union

                  Comment

                  • CBFalconer

                    #10
                    Re: What is const char * const *p;

                    Dan Pop wrote:[color=blue]
                    > CBFalconer <cbfalconer@yah oo.com> writes:[color=green]
                    >> "E. Robert Tisdale" wrote:[color=darkred]
                    >>> Vijay Kumar R. Zanvar wrote:
                    >>>[/color]
                    >>... snip ...[color=darkred]
                    >>>
                    >>>> 3. Then, how do I assert that a given object is aligned, say,
                    >>>> at 32-byte boundary?
                    >>>
                    >>> assert(p == ((p + 31)&(~31)));[/color]
                    >>
                    >> Undefined behaviour.[/color]
                    >
                    > Can I have the chapter and verse? I always thought it was a
                    > constraint violation:
                    >
                    > 6.5.10 Bitwise AND operator
                    >
                    > Syntax
                    >
                    > 1 AND-expression:
                    > equality-expression
                    > AND-expression & equality-expression
                    >
                    > Constraints
                    >
                    > 2 Each of the operands shall have integer type.
                    >[color=green]
                    >> This is an operation that can only be performed outside the C language,[/color]
                    >
                    > Wrong again: it can be performed without violating the C language
                    > specification, by converting the pointer to a suitable integer type.
                    >[color=green]
                    > >and is non-portable.[/color]
                    >
                    > This is correct, in theory, at least.[/color]

                    Thanks for the corrections. However the theme of my reply "Tisdale
                    is in serious error again" still holds, together with "don't do
                    that". Even if the conversions work, there is no guarantee that
                    any such results indicate anything whatsoever about alignment.

                    --
                    Chuck F (cbfalconer@yah oo.com) (cbfalconer@wor ldnet.att.net)
                    Available for consulting/temporary embedded and systems.
                    <http://cbfalconer.home .att.net> USE worldnet address!

                    Comment

                    • Dan Pop

                      #11
                      Re: What is const char * const *p;

                      In <41ADFA05.6C061 5A8@yahoo.com> CBFalconer <cbfalconer@yah oo.com> writes:
                      [color=blue]
                      >that". Even if the conversions work, there is no guarantee that
                      >any such results indicate anything whatsoever about alignment.[/color]

                      This is a quality of implementation issue and you won't find many
                      implementors foolishly ignoring it. If the standard allows such
                      conversions, it is because they are the ONLY *reasonably* portable
                      solution to this class of problems.

                      Dan
                      --
                      Dan Pop
                      DESY Zeuthen, RZ group
                      Email: Dan.Pop@ifh.de
                      Currently looking for a job in the European Union

                      Comment

                      • Tim Rentsch

                        #12
                        Re: What is const char * const *p;

                        CBFalconer <cbfalconer@yah oo.com> writes:
                        [color=blue]
                        > "E. Robert Tisdale" wrote:[color=green]
                        > >
                        > > assert(p == ((p + 31)&(~31)));[/color]
                        >
                        > Undefined behaviour. This is an operation that can only be
                        > performed outside the C language, and is non-portable.[/color]

                        A technical detail here, but one that I think is important.

                        The operation can be performed inside the C language. It's
                        just that it produces undefined behavior when it does.

                        The flip side of that view seems, well, at least unuseful. Otherwise,
                        we'd have to say that any program that dereferences a NULL pointer
                        isn't a C program. Whether something is written in the C language
                        should be something that can be determined statically. Of course, it
                        may be true that executing a C program produces undefined behavior,
                        but it's still C.

                        Comment

                        • Keith Thompson

                          #13
                          Re: What is const char * const *p;

                          Tim Rentsch <txr@alumnus.ca ltech.edu> writes:[color=blue]
                          > CBFalconer <cbfalconer@yah oo.com> writes:[color=green]
                          >> "E. Robert Tisdale" wrote:[color=darkred]
                          >> >
                          >> > assert(p == ((p + 31)&(~31)));[/color]
                          >>
                          >> Undefined behaviour. This is an operation that can only be
                          >> performed outside the C language, and is non-portable.[/color]
                          >
                          > A technical detail here, but one that I think is important.
                          >
                          > The operation can be performed inside the C language. It's
                          > just that it produces undefined behavior when it does.[/color]

                          The operation being attempted can be performed inside the C language,
                          but not the way ERT presents it. The bitwise "&" operator cannot
                          legally be applied to a pointer value. It's a constraint violation,
                          not merely undefined behavior.

                          Incidentally, I've worked on systems where you can't determine the
                          alignment of a pointer value just by examining its low-order bits.

                          --
                          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

                          • Tim Rentsch

                            #14
                            Re: What is const char * const *p;

                            Keith Thompson <kst-u@mib.org> writes:
                            [color=blue]
                            > Tim Rentsch <txr@alumnus.ca ltech.edu> writes:[color=green]
                            > > CBFalconer <cbfalconer@yah oo.com> writes:[color=darkred]
                            > >> "E. Robert Tisdale" wrote:
                            > >> >
                            > >> > assert(p == ((p + 31)&(~31)));
                            > >>
                            > >> Undefined behaviour. This is an operation that can only be
                            > >> performed outside the C language, and is non-portable.[/color]
                            > >
                            > > A technical detail here, but one that I think is important.
                            > >
                            > > The operation can be performed inside the C language. It's
                            > > just that it produces undefined behavior when it does.[/color]
                            >
                            > The operation being attempted can be performed inside the C language,
                            > but not the way ERT presents it. The bitwise "&" operator cannot
                            > legally be applied to a pointer value.[/color]

                            Right. Of course what I meant was that the operation of testing a
                            pointer for alignment can be (non-portably) performed by using an '&'
                            operation. There does need to be a cast of the pointer to perform
                            the '&' operation.

                            Comment

                            Working...