Flexible arrays - v confused

Discussion in 'C Programming' started by mechanicfem@googlemail.com, Feb 14, 2006.

  1. Guest

    I thought (as they're in c99) that flexible arrays were there for a
    number of reasons - but I also thought they'd be great for stepping
    into structures (say) that were aligned in memory after (say) a header
    struct, e.g.:

    struct element
    {
    int a;
    int b;
    };
    typedef struct element elem;

    struct header
    {
    int a;
    elem element[];
    };
    typedef struct header head;
    ....

    head * p;
    ....

    (p -> element)[10] = ...;

    However, the same 'trick' can be done if header contained this

    elem * element;
    };

    So, I can't really see the benefit of using empty array notation here.
    And anyway, how would you malloc some memory for element when it's an
    array type - surely p -> element = malloc... is an error, as element is
    an array, and so can't be assigned to? That leaves me thinking that to
    get it to work like that, maybe you should malloc a lump of memory,
    then cast the address to a header *, access element, and then index
    into that. But again, you could do this using straight forward pointer
    notation in the declaration of element?

    So, then I thought, well, maybe the notation would allow me to
    initialise a struct ...

    struct foo
    {
    int a;
    char b[];
    };

    struct foo s = {10, {'f', 'o', 'o'}};

    But gcc doesn't like that (with -std=c99), and again, if b were
    declared char * b, surely this is illegal ...

    struct foo s = {10, {"foo"}};

    So, Istarting from 'they must be great for a number of reasons' I'm now
    totally confused as to what flexible arrays can do for you. Could
    someone please help me?

    x

    Jo
    , Feb 14, 2006
    #1
    1. Advertising

  2. Zero Guest

    #include <stdio.h>
    #include <stdlib.h>

    struct element
    {
    int a;
    int b;
    };

    typedef struct element elem;

    struct header
    {
    int a;
    elem element[];
    };

    typedef struct header head;





    int main(int argc, char *argv[])
    {


    head *p;


    p = malloc ( sizeof(struct header) + sizeof(struct element) * 10);


    system("PAUSE");
    return 0;
    }


    This declares a pointer p of type head
    which allocates memory for one struct header and 10 elements
    of type struct element.
    Zero, Feb 14, 2006
    #2
    1. Advertising

  3. Default User Guest

    Zero wrote:


    > This declares a pointer p of type head
    > which allocates memory for one struct header and 10 elements
    > of type struct element.


    That's nice, so what? (See below).



    Brian

    --
    Please quote enough of the previous message for context. To do so from
    Google, click "show options" and use the Reply shown in the expanded
    header.
    Default User, Feb 14, 2006
    #3
  4. Chris Torek Guest

    In article <>
    <> wrote:
    >I thought (as they're in c99) that flexible arrays were there for a
    >number of reasons ...


    They really exist for just one reason: to legitimize the old
    "struct hack" (as it is called in the FAQ).

    To review for a moment, the "struct hack" is done something like this:

    #include <stdlib.h>

    struct vector {
    size_t n; /* number of values in the vector */
    double val[1]; /* actually size n */
    };

    struct vector *vec_new(size_t n) {
    struct vector *p;

    /* need n-1 here because the array has an "extra" element */
    p = malloc(sizeof *p + (n ? n - 1 : 0) * sizeof p->val[0]);
    if (p != NULL) {
    p->n = n;
    while (n)
    p->val[--n] = 0.0;
    }
    return p;
    }

    void vec_free(struct vector *p) {
    free(p);
    }

    double vec_access(struct vector *p, size_t i) {
    if (i >= p->n)
    panic("vec_access: nonexistent element %lu\n", (unsigned long)i);
    return p->val;
    }

    To use a C99 "flexible array" structure member, we simply remove
    the constant "1" and get rid of the code that subtracts 1 from the
    computation passed to malloc(). This simplifies vec_new:

    p = malloc(sizeof *p + n * sizeof p->val[0]);

    and otherwise has no effect on the machine-level code produced,
    except that it *must* actually work, whereas the pre-C99 version
    was allowed to produce code that misbehaved at runtime. (That is,
    the "struct hack" is not 100% legitimate, although no one has
    produced examples of machines on which it does not work.)

    >However, the same 'trick' can be done if [the struct that has the
    >Flexible Array Member] contained [a pointer] ...


    In other words, we could equally write:

    struct vector {
    size_t n;
    double *val;
    };

    struct vector *vec_new(size_t n) {
    struct vector *p;

    p = malloc(sizeof *p);
    if (p != NULL) {
    p->val = malloc(n * sizeof *p->val);
    if (p->val != NULL) {
    p->n = n;
    while (n)
    p->val[--n] = 0.0;
    } else {
    free(p);
    p = NULL;
    }
    }
    return p;
    }

    void vec_free(struct vector *p) {
    free(p->val); /* or perhaps check p!=NULL first */
    free(p);
    }

    The rest of the code remains unchanged.

    >So, I can't really see the benefit of using empty array notation here.


    The advantage to using the F.A.M. (or the struct hack) is that we
    avoid the second malloc() call and the associated extra source code,
    and the underlying machine code tends to be more efficient as well
    (although the latter is certainly never promised).

    >And anyway, how would you malloc some memory for element when it's an
    >array type ...


    As shown above.

    >So, then I thought, well, maybe the notation would allow me to
    >initialise a struct ...


    There is a way to map the F.A.M. or struct hack onto an actual,
    initialized instance. This is at least "technically iffy", however,
    as there is no guarantee that the offets of the members of the
    "inflexible" structure match those of the "flexible" structure.

    >struct foo
    >{
    > int a;
    > char b[];
    >};
    >
    >struct foo s = {10, {'f', 'o', 'o'}};


    You cannot do this; but you can do:

    struct foo {
    int a;
    char b[];
    };
    struct foo_with_b_size_3 {
    int a;
    char b[3];
    } s = { 10, { 'f', 'o', 'o' } };

    struct foo *get_s(void) {
    return (struct foo *)&s;
    }

    This runs into that "technically iffy" problem (although, again,
    it seems to work on all real implementations). The fact that it
    requires a pointer cast is reason enough to be suspicious: any code
    that requires a pointer cast is probably skating on thin ice.
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
    Chris Torek, Feb 14, 2006
    #4
  5. Ben Hinkle Guest


    > So, I can't really see the benefit of using empty array notation here.
    > And anyway, how would you malloc some memory for element when it's an
    > array type - surely p -> element = malloc... is an error, as element is
    > an array, and so can't be assigned to? That leaves me thinking that to
    > get it to work like that, maybe you should malloc a lump of memory,
    > then cast the address to a header *, access element, and then index
    > into that. But again, you could do this using straight forward pointer
    > notation in the declaration of element?


    The difference is that with a pointer the struct would have a data layout
    like
    int, elem*
    where the pointer would point to an array of elem. With flexible arrays the
    data layout looks like
    int, elem[0], elem[1], etc
    where you allocates the struct and the flexible array all in one block.
    Think of the flexible array as if there were a fixed size like elem
    element[10] and then allow the "10" to be defined at run time. The other
    reply gave an example malloc call.
    Ben Hinkle, Feb 14, 2006
    #5
  6. Guest

    Chris Torek wrote:
    > In article <>
    > <> wrote:
    > >I thought (as they're in c99) that flexible arrays were there for a
    > >number of reasons ...

    >
    > They really exist for just one reason: to legitimize the old
    > "struct hack" (as it is called in the FAQ).
    >
    > To review for a moment, the "struct hack" is done something like this:
    >
    > #include <stdlib.h>
    >
    > struct vector {
    > size_t n; /* number of values in the vector */
    > double val[1]; /* actually size n */
    > };
    >
    > struct vector *vec_new(size_t n) {
    > struct vector *p;
    >
    > /* need n-1 here because the array has an "extra" element */
    > p if (p ! p->n while (n)
    > p->val[--n] }
    > return p;
    > }
    >
    > void vec_free(struct vector *p) {
    > free(p);
    > }
    >
    > double vec_access(struct vector *p, size_t i) {
    > if (i > panic("vec_access: nonexistent element %lu\n", (unsigned long)i);
    > return p->val;
    > }
    >
    > To use a C99 "flexible array" structure member, we simply remove
    > the constant "1" and get rid of the code that subtracts 1 from the
    > computation passed to malloc(). This simplifies vec_new:
    >
    > p
    > and otherwise has no effect on the machine-level code produced,
    > except that it *must* actually work, whereas the pre-C99 version
    > was allowed to produce code that misbehaved at runtime. (That is,
    > the "struct hack" is not 100% legitimate, although no one has
    > produced examples of machines on which it does not work.)
    >
    > >However, the same 'trick' can be done if [the struct that has the
    > >Flexible Array Member] contained [a pointer] ...

    >
    > In other words, we could equally write:
    >
    > struct vector {
    > size_t n;
    > double *val;
    > };
    >
    > struct vector *vec_new(size_t n) {
    > struct vector *p;
    >
    > p if (p ! p->val if (p->val ! p->n while (n)
    > p->val[--n] } else {
    > free(p);
    > p }
    > }
    > return p;
    > }
    >
    > void vec_free(struct vector *p) {
    > free(p->val); /* or perhaps check p!=NULL first */
    > free(p);
    > }
    >
    > The rest of the code remains unchanged.
    >
    > >So, I can't really see the benefit of using empty array notation here.

    >
    > The advantage to using the F.A.M. (or the struct hack) is that we
    > avoid the second malloc() call and the associated extra source code,
    > and the underlying machine code tends to be more efficient as well
    > (although the latter is certainly never promised).
    >
    > >And anyway, how would you malloc some memory for element when it's an
    > >array type ...

    >
    > As shown above.
    >
    > >So, then I thought, well, maybe the notation would allow me to
    > >initialise a struct ...

    >
    > There is a way to map the F.A.M. or struct hack onto an actual,
    > initialized instance. This is at least "technically iffy", however,
    > as there is no guarantee that the offets of the members of the
    > "inflexible" structure match those of the "flexible" structure.
    >
    > >struct foo
    > >{
    > > int a;
    > > char b[];
    > >};
    > >
    > >struct foo s

    > You cannot do this; but you can do:
    >
    > struct foo {
    > int a;
    > char b[];
    > };
    > struct foo_with_b_size_3 {
    > int a;
    > char b[3];
    > } s
    > struct foo *get_s(void) {
    > return (struct foo *)&s;
    > }
    >
    > This runs into that "technically iffy" problem (although, again,
    > it seems to work on all real implementations). The fact that it
    > requires a pointer cast is reason enough to be suspicious: any code
    > that requires a pointer cast is probably skating on thin ice.
    > --


    Thanks to all that replied. The veil has been lifted.

    However, couple of questions about the code.

    If you simply knocked this up to show the methods etc, what follows is
    probably not too interesting, or worth commenting upon. However, there
    was a couple of things that made me think, so I include them here to
    see if there's any comment etc.

    Although sizeof never executes its 'arg' (don't know if those are the
    right terms, but I'm sure they're good enough to be understood), I'd
    personally go with
    sizeof(vector) --rather than-- sizeof *p

    To perhaps calm the nerves of any maintenence programmer that see an
    auto *p that *seems* to be /dereferenced/ ?

    The former, of course, would need a typedef struct vector vector -
    which I also think would make the code a little easier to read.

    On vec_access, why not return a double * to allow both read and write
    access, e.g., using return &(p->val);

    x

    Jo
    , Feb 15, 2006
    #6
  7. Alex Fraser Guest

    <> wrote in message
    news:...
    [snip]
    > Although sizeof never executes its 'arg' (don't know if those are the
    > right terms, but I'm sure they're good enough to be understood),


    I think "evaluates" and "operand" are the terms you are looking for.

    > I'd personally go with
    > sizeof(vector) --rather than-- sizeof *p
    >
    > To perhaps calm the nerves of any maintenence programmer that see an
    > auto *p that *seems* to be /dereferenced/ ?


    If, perhaps as a maintenance programmer, I see the following line of code:

    p = malloc(sizeof *p);

    I immediately know that the call requests allocation of the right amount of
    space for one of whatever p points to.

    OTOH, if I see something like:

    p = malloc(sizeof (struct vector));

    I first have to remember or check that p has the correct type.

    Alex
    Alex Fraser, Feb 15, 2006
    #7
  8. Guest

    Alex Fraser wrote:
    > <> wrote in message
    > news:...
    > [snip]
    > > Although sizeof never executes its 'arg' (don't know if those are the
    > > right terms, but I'm sure they're good enough to be understood),

    >
    > I think "evaluates" and "operand" are the terms you are looking for.
    >
    > > I'd personally go with
    > > sizeof(vector) --rather than-- sizeof *p
    > >
    > > To perhaps calm the nerves of any maintenence programmer that see an
    > > auto *p that *seems* to be /dereferenced/ ?

    >
    > If, perhaps as a maintenance programmer, I see the following line of code:
    >
    > p = malloc(sizeof *p);
    >
    > I immediately know that the call requests allocation of the right amount of
    > space for one of whatever p points to.
    >
    > OTOH, if I see something like:
    >
    > p = malloc(sizeof (struct vector));
    >
    > I first have to remember or check that p has the correct type.


    Hmmm, yes, that's a good observation, and reason for doing it. Thanks.

    x

    Jo
    , Feb 15, 2006
    #8
  9. writes:
    [...]
    > Although sizeof never executes its 'arg' (don't know if those are the
    > right terms, but I'm sure they're good enough to be understood), I'd
    > personally go with
    > sizeof(vector) --rather than-- sizeof *p
    >
    > To perhaps calm the nerves of any maintenence programmer that see an
    > auto *p that *seems* to be /dereferenced/ ?


    The operand of the sizeof operator is not evaluated *unless* the
    operand's type is a variable length array (which isn't the case here).

    Somebody else explained the reason for using sizeof *p, but I'll
    expand on it a little.

    Given:

    some_type *ptr;
    ...
    ptr = malloc(sizeof(some_type));

    it's very easy to change the declaration to

    some_other_type *ptr;

    and forget to change the argument to the malloc() call. If you use
    the recommended form:

    ptr = malloc(sizeof *ptr);

    that's not an issue.

    > The former, of course, would need a typedef struct vector vector -
    > which I also think would make the code a little easier to read.


    No, a typedef isn't needed:

    struct vector *ptr;
    ptr = malloc(sizeof struct vector);

    is perfectly legal. (And in my opinion, routinely using typedefs for
    all structs is not useful; it creates two distinct names for each type
    when one name, "struct vector" is quite sufficient.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Feb 15, 2006
    #9
  10. Old Wolf Guest

    Keith Thompson wrote:
    >
    > struct vector *ptr;
    > ptr = malloc(sizeof struct vector);
    >
    > is perfectly legal.


    sizeof(struct vector)

    When you are in the habit of omitting the brackets for "sizeof var",
    it's easy to forget to include them for "sizeof(typename)" .
    Old Wolf, Feb 15, 2006
    #10
  11. "Old Wolf" <> writes:
    > Keith Thompson wrote:
    >>
    >> struct vector *ptr;
    >> ptr = malloc(sizeof struct vector);
    >>
    >> is perfectly legal.

    >
    > sizeof(struct vector)
    >
    > When you are in the habit of omitting the brackets for "sizeof var",
    > it's easy to forget to include them for "sizeof(typename)" .


    Absolutely correct; thanks for catching my error.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Feb 15, 2006
    #11
  12. Joe Wright Guest

    Keith Thompson wrote:
    > "Old Wolf" <> writes:
    >
    >>Keith Thompson wrote:
    >>
    >>> struct vector *ptr;
    >>> ptr = malloc(sizeof struct vector);
    >>>
    >>>is perfectly legal.

    >>
    >> sizeof(struct vector)
    >>
    >>When you are in the habit of omitting the brackets for "sizeof var",
    >>it's easy to forget to include them for "sizeof(typename)" .

    >
    >
    > Absolutely correct; thanks for catching my error.
    >

    Also it is interesting to name things consistently. At my house..

    parens (parentheses) look like ()
    brackets look like [] and
    braces look like {}

    I use space in 'sizeof (typename)' so that sizeof operator cannot so
    easily be confused with a function.

    --
    Joe Wright
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
    Joe Wright, Feb 15, 2006
    #12
  13. Joe Wright <> writes:
    > Keith Thompson wrote:
    >> "Old Wolf" <> writes:
    >>>Keith Thompson wrote:
    >>>
    >>>> struct vector *ptr;
    >>>> ptr = malloc(sizeof struct vector);
    >>>>
    >>>>is perfectly legal.
    >>>
    >>> sizeof(struct vector)
    >>>
    >>>When you are in the habit of omitting the brackets for "sizeof var",
    >>>it's easy to forget to include them for "sizeof(typename)" .

    >> Absolutely correct; thanks for catching my error.
    >>

    > Also it is interesting to name things consistently. At my house..
    >
    > parens (parentheses) look like ()
    > brackets look like [] and
    > braces look like {}


    That's what I call them too, but I think common usage differs outside
    the US. When it doubt, show the actual characters.

    > I use space in 'sizeof (typename)' so that sizeof operator cannot so
    > easily be confused with a function.


    That's a good idea.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Feb 16, 2006
    #13
  14. Guest

    Chris Torek wrote:
    > #include <stdlib.h>
    > struct vector {
    > size_t n; /* number of values in the vector */
    > double val[1]; /* actually size n */
    > };
    >
    > struct vector *vec_new(size_t n) {
    > struct vector *p;
    >
    > /* need n-1 here because the array has an "extra" element */
    > p = malloc(sizeof *p + (n ? n - 1 : 0) * sizeof p->val[0]);


    I do this as follows:

    p = (struct vector *) malloc (offsetof (struct vector, val) +
    n * sizeof (p->val[0]));

    Which means I need a #include <stddef.h>

    --
    Paul Hsieh
    http://www.pobox.com/~qed/
    http://bstring.sf.net/
    , Feb 16, 2006
    #14
  15. writes:
    > Chris Torek wrote:
    >> #include <stdlib.h>
    >> struct vector {
    >> size_t n; /* number of values in the vector */
    >> double val[1]; /* actually size n */
    >> };
    >>
    >> struct vector *vec_new(size_t n) {
    >> struct vector *p;
    >>
    >> /* need n-1 here because the array has an "extra" element */
    >> p = malloc(sizeof *p + (n ? n - 1 : 0) * sizeof p->val[0]);

    >
    > I do this as follows:
    >
    > p = (struct vector *) malloc (offsetof (struct vector, val) +
    > n * sizeof (p->val[0]));
    >
    > Which means I need a #include <stddef.h>


    Why do you uselessly cast the result of malloc()?

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Feb 16, 2006
    #15
  16. Guest

    Keith Thompson wrote:
    > writes:
    > > Chris Torek wrote:
    > >> #include <stdlib.h>
    > >> struct vector {
    > >> size_t n; /* number of values in the vector */
    > >> double val[1]; /* actually size n */
    > >> };
    > >>
    > >> struct vector *vec_new(size_t n) {
    > >> struct vector *p;
    > >>
    > >> /* need n-1 here because the array has an "extra" element */
    > >> p = malloc(sizeof *p + (n ? n - 1 : 0) * sizeof p->val[0]);

    > >
    > > I do this as follows:
    > >
    > > p = (struct vector *) malloc (offsetof (struct vector, val) +
    > > n * sizeof (p->val[0]));
    > >
    > > Which means I need a #include <stddef.h>

    >
    > Why do you uselessly cast the result of malloc()?


    Because I like to use automatic error detection tools when I program,
    and that includes using a C++ compiler (which has stricter type
    checking). It means I have to conceed to things like the above in
    order to gain the benefit of stronger type checking elsewhere in my
    programs.

    So if you take the opposite point of view, would it be fair to say that
    you avoid things like Lint and ignore warning messages coming from your
    compiler? Or are you saying that anything superfluous, like comments
    and whitespace, should be eradicated from code?

    --
    Paul Hsieh
    http://www.pobox.com/~qed/
    http://bstring.sf.net/
    , Feb 16, 2006
    #16
  17. writes:
    > Keith Thompson wrote:

    [...]
    >> Why do you uselessly cast the result of malloc()?

    >
    > Because I like to use automatic error detection tools when I program,
    > and that includes using a C++ compiler (which has stricter type
    > checking). It means I have to conceed to things like the above in
    > order to gain the benefit of stronger type checking elsewhere in my
    > programs.
    >
    > So if you take the opposite point of view, would it be fair to say that
    > you avoid things like Lint and ignore warning messages coming from your
    > compiler? Or are you saying that anything superfluous, like comments
    > and whitespace, should be eradicated from code?


    Yes, absolutely, because you're always right and anyone who disagrees
    with you must be a complete idiot. Thank you for bringing this to my
    attention.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Feb 16, 2006
    #17
  18. Guest

    Keith Thompson wrote:
    > writes:
    > > Keith Thompson wrote:

    > [...]
    > >> Why do you uselessly cast the result of malloc()?

    > >
    > > Because I like to use automatic error detection tools when I program,
    > > and that includes using a C++ compiler (which has stricter type
    > > checking). It means I have to conceed to things like the above in
    > > order to gain the benefit of stronger type checking elsewhere in my
    > > programs.
    > >
    > > So if you take the opposite point of view, would it be fair to say that
    > > you avoid things like Lint and ignore warning messages coming from your
    > > compiler? Or are you saying that anything superfluous, like comments
    > > and whitespace, should be eradicated from code?

    >
    > Yes, absolutely, because you're always right and anyone who disagrees
    > with you must be a complete idiot. Thank you for bringing this to my
    > attention.


    You intentionally instigated this. You used the language "uselessly"
    and your canned argument against this cast is well known to me, and you
    know that. So you respond with this question with the intention of
    laying this pathetic trap. But, if you've ever bothered to read my
    posts, you've known my counter argument before this post.

    My reducto ad absurdum in the second paragraph is meant to address the
    position "if you take the opposite point of view". If you understood
    what I was saying rather than taking an antagonistic-only stance you
    would have realized that what I was saying is that the problem is that
    you have not clarified the basis for your point of view, and unless its
    insane the ball is in your court to explain why you want to remove this
    "useless" cast.

    --
    Paul Hsieh
    http://www.pobox.com/~qed/
    http://bstring.sf.net/
    , Feb 17, 2006
    #18
  19. Richard Bos Guest

    wrote:

    > Keith Thompson wrote:
    > > writes:
    > > > p = (struct vector *) malloc (offsetof (struct vector, val) +
    > > > n * sizeof (p->val[0]));
    > > >
    > > > Which means I need a #include <stddef.h>

    > >
    > > Why do you uselessly cast the result of malloc()?

    >
    > Because I like to use automatic error detection tools when I program,
    > and that includes using a C++ compiler (which has stricter type
    > checking). It means I have to conceed to things like the above in
    > order to gain the benefit of stronger type checking elsewhere in my
    > programs.


    So in order to gain a few dubious warnings which quite possibly won't
    even apply to the language you're writing in, you prevent your real
    compiler from spotting what would be a read and potentially dangerous
    mistake?

    Sheer brilliance.

    Richard
    Richard Bos, Feb 17, 2006
    #19
  20. Guest

    Richard Bos wrote:
    > wrote:
    > > Keith Thompson wrote:
    > > > writes:
    > > > > p = (struct vector *) malloc (offsetof (struct vector, val) +
    > > > > n * sizeof (p->val[0]));
    > > > >
    > > > > Which means I need a #include <stddef.h>
    > > >
    > > > Why do you uselessly cast the result of malloc()?

    > >
    > > Because I like to use automatic error detection tools when I program,
    > > and that includes using a C++ compiler (which has stricter type
    > > checking). It means I have to conceed to things like the above in
    > > order to gain the benefit of stronger type checking elsewhere in my
    > > programs.

    >
    > So in order to gain a few dubious warnings which quite possibly won't
    > even apply to the language you're writing in, you prevent your real
    > compiler from spotting what would be a read and potentially dangerous
    > mistake?


    C++ compilers also enforce prototype predeclarations (so would C99
    compilers if they existed). So exactly which dangerous mistake do you
    think I am going to miss?

    --
    Paul Hsieh
    http://www.pobox.com/~qed/
    http://bstring.sf.net/
    , Feb 17, 2006
    #20
    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. Replies:
    2
    Views:
    341
  2. arnuld
    Replies:
    19
    Views:
    670
    Jacek Dziedzic
    Mar 30, 2007
  3. Replies:
    3
    Views:
    255
  4. Philipp
    Replies:
    21
    Views:
    1,101
    Philipp
    Jan 20, 2009
  5. Andrea Taverna

    Flexible arrays getting in the way?

    Andrea Taverna, Apr 3, 2009, in forum: C Programming
    Replies:
    4
    Views:
    1,289
    Eric Sosman
    Apr 5, 2009
Loading...

Share This Page