would C be easier to read if...

Discussion in 'C Programming' started by Robert Smith, Apr 3, 2008.

  1. Robert Smith

    Robert Smith Guest

    some of the syntax wasn't overloaded so much...

    Was just musing that if pointer de-referencing and pointer-to-type had
    seperate syntax (ie use a character other than '*' for one of them) it would
    make things much easier to read. You wouldn't get stuff like:

    pthread_create(&thread, NULL, (void *(*)(void*))ThreadProc, (void
    *)parameter);
     
    Robert Smith, Apr 3, 2008
    #1
    1. Advertising

  2. Robert Smith

    Chris Dollin Guest

    Robert Smith wrote:

    > some of the syntax wasn't overloaded so much...
    >
    > Was just musing that if pointer de-referencing and pointer-to-type had
    > seperate syntax (ie use a character other than '*' for one of them) it would
    > make things much easier to read. You wouldn't get stuff like:
    >
    > pthread_create(&thread, NULL, (void *(*)(void*))ThreadProc, (void
    > *)parameter);


    Surely either `ThreadProc` is already the right type, in which case
    the cast can and should be discarded, or it isn't, in which case
    the cast is a bug waiting to manifest and `ThreadProc` should be
    fixed.

    Yes?

    --
    "In vain I have struggled. It will not do." /Pride and Prejudice/

    Hewlett-Packard Limited Cain Road, Bracknell, registered no:
    registered office: Berks RG12 1HN 690597 England
     
    Chris Dollin, Apr 3, 2008
    #2
    1. Advertising

  3. Chris Dollin writes:
    >Robert Smith wrote:
    >> pthread_create(&thread, NULL, (void *(*)(void*))ThreadProc, (void
    >> *)parameter);

    >
    > Surely either `ThreadProc` is already the right type, in which case
    > the cast can and should be discarded, or it isn't, in which case
    > the cast is a bug waiting to manifest and `ThreadProc` should be
    > fixed.
    >
    > Yes?


    And hopefully 'parameter' is a non-const pointer so the void* cast
    can be dropped too.

    The times where you do need to clutter the code with unreadable
    type casts, it may make sense to typedef the offending type.

    --
    Hallvard
     
    Hallvard B Furuseth, Apr 3, 2008
    #3
  4. "Robert Smith" <> writes:

    > some of the syntax wasn't overloaded so much...
    >
    > Was just musing that if pointer de-referencing and pointer-to-type had
    > seperate syntax (ie use a character other than '*' for one of them) it would
    > make things much easier to read. You wouldn't get stuff like:
    >
    > pthread_create(&thread, NULL, (void *(*)(void*))ThreadProc, (void
    > *)parameter);


    All the *s there have the same meaning, don't they? How would
    changing the symbol help?

    --
    Ben.
     
    Ben Bacarisse, Apr 3, 2008
    #4
  5. Robert Smith

    Guest

    On Apr 3, 5:08 pm, Hallvard B Furuseth <>
    wrote:
    > Chris Dollin writes:
    > >Robert Smith wrote:
    > >> some of the syntax wasn't overloaded so much...

    C is old. Back then a lot of symbols were missing from the keyboard,
    thus C has a simple character set. (and alternatives such as digraphs
    and trigraphs which are not that used, but some regulars claim to have
    used them under certain circumstances)
    I don't think adding/changing symbols would make the language simpler.
    > >> pthread_create(&thread, NULL, (void *(*)(void*))ThreadProc, (void
    > >> *)parameter);

    >
    > > Surely either `ThreadProc` is already the right type, in which case
    > > the cast can and should be discarded, or it isn't, in which case
    > > the cast is a bug waiting to manifest and `ThreadProc` should be
    > > fixed.

    >
    > > Yes?

    >
    > And hopefully 'parameter' is a non-const pointer so the void* cast
    > can be dropped too.

    Even if parameter was const char * const parameter = "hello world";
    the cast can still be omitted, as long as ThreadProc does not try to
    mutate what is pointed to by parameter.
     
    , Apr 3, 2008
    #5
  6. Robert Smith wrote:
    > some of the syntax wasn't overloaded so much...


    Overloaded symbols are a problem in C, yes. But in this case it's a
    design feature that syntax for declaring a variable is the same as for
    using it. As a result there is one and not two syntaxes you need to
    learn in order to dig your way through a complex use of a variable.

    wrote:
    >On Apr 3, 5:08 pm, Hallvard B Furuseth <> wrote:
    >(...)
    >>>> pthread_create(&thread, NULL, (void *(*)(void*))ThreadProc, (void
    >>>> *)parameter);

    >>(...)
    >> And hopefully 'parameter' is a non-const pointer so the void* cast
    >> can be dropped too.

    >
    > Even if parameter was const char * const parameter = "hello world";
    > the cast can still be omitted, as long as ThreadProc does not try to
    > mutate what is pointed to by parameter.


    No. pthread_create() takes a void* 3rd parameter. It's an error
    to assign or pass a "pointer to const" to a "pointer to not-const".
    On the other hand the const may be cast away, and if the underlying
    object was not created with 'const' type it may be mutated.

    --
    Hallvard
     
    Hallvard B Furuseth, Apr 3, 2008
    #6
  7. Robert Smith

    Guest

    On Apr 3, 6:17 pm, Hallvard B Furuseth <>
    wrote:
    > Robert Smith wrote:
    > > some of the syntax wasn't overloaded so much...

    >
    > Overloaded symbols are a problem in C, yes. But in this case it's a
    > design feature that syntax for declaring a variable is the same as for
    > using it. As a result there is one and not two syntaxes you need to
    > learn in order to dig your way through a complex use of a variable.
    >
    > wrote:
    > >On Apr 3, 5:08 pm, Hallvard B Furuseth <> wrote:
    > >(...)
    > >>>> pthread_create(&thread, NULL, (void *(*)(void*))ThreadProc, (void
    > >>>> *)parameter);
    > >>(...)
    > >> And hopefully 'parameter' is a non-const pointer so the void* cast
    > >> can be dropped too.

    >
    > > Even if parameter was const char * const parameter = "hello world";
    > > the cast can still be omitted, as long as ThreadProc does not try to
    > > mutate what is pointed to by parameter.

    >
    > No. pthread_create() takes a void* 3rd parameter. It's an error
    > to assign or pass a "pointer to const" to a "pointer to not-const".

    I don't remember what the POSIX standard says about this, but in C it
    is not. Ofcourse, pthread_create is not mentioned in the C99 standard,
    however, what I demonstrate here is a function taking void *, and
    passing to that function a const char * const. Note that this function
    could be the callback to pthread_create. In pthread_create()'s manual
    there is no mention of *requiring* the last argument to be modifiable.

    Here's a perfectly conforming C99 program

    #include <stdio.h>
    int foo(void *);
    int main(void) {
    const char * const p = "hello world";
    foo(p);
    return 0;
    }
    int foo(void *p) { return puts(p); }
     
    , Apr 3, 2008
    #7
  8. writes:
    >On Apr 3, 6:17 pm, Hallvard B Furuseth <> wrote:
    >>> Even if parameter was const char * const parameter = "hello world";
    >>> the cast can still be omitted, as long as ThreadProc does not try to
    >>> mutate what is pointed to by parameter.

    >>
    >> No. pthread_create() takes a void* 3rd parameter. It's an error
    >> to assign or pass a "pointer to const" to a "pointer to not-const".

    >
    > I don't remember what the POSIX standard says about this, but in C it
    > is not.


    You are confusing something with something. Half the purpose of the
    const qualifier is that the compiler's type checking can help you catch
    assignments to read-only objects.

    > (...) what I demonstrate here is a function taking void *, and
    > passing to that function a const char * const.


    void* isn't that magical. You can pass a char* to a void* or
    a const char* to a const void*. Not a const char* to a void*.

    > (...) Here's a perfectly conforming C99 program (...)


    I'm not up to digging through the standard at the moment, but if you
    compile it with "gcc -std=c99 -pedantic-errors" and bugreport the
    resulting error message, maybe they'll tell you where to find it:)

    --
    Hallvard
     
    Hallvard B Furuseth, Apr 3, 2008
    #8
  9. Robert Smith

    Guest

    On Apr 3, 6:47 pm, Hallvard B Furuseth <>
    wrote:
    > writes:
    > >On Apr 3, 6:17 pm, Hallvard B Furuseth <> wrote:
    > >>> Even if parameter was const char * const parameter = "hello world";
    > >>> the cast can still be omitted, as long as ThreadProc does not try to
    > >>> mutate what is pointed to by parameter.

    >
    > >> No. pthread_create() takes a void* 3rd parameter. It's an error
    > >> to assign or pass a "pointer to const" to a "pointer to not-const".

    >
    > > I don't remember what the POSIX standard says about this, but in C it
    > > is not.

    >
    > You are confusing something with something. Half the purpose of the
    > const qualifier is that the compiler's type checking can help you catch
    > assignments to read-only objects.

    Well, that's *your* opinion. My opinion is that const is there for
    optimization and documentation.
    Ie foo(const int *) informs the programmer foo shall not modify what
    is pointed to by its argument.
    >
    > > (...) what I demonstrate here is a function taking void *, and
    > > passing to that function a const char * const.

    >
    > void* isn't that magical. You can pass a char* to a void* or
    > a const char* to a const void*. Not a const char* to a void*.

    That is not true, and it's not about void *'s "magic". You can also
    assign a const char * to a char * and still have a conforming program.
    Also, while thinking about it, pthread_create shouldn't be able to
    access what is pointed to by its last argument. Unless POSIX says
    something about it (and I'm positive it does not) then it's POSIX
    conforming too.

    > > (...) Here's a perfectly conforming C99 program (...)

    >
    > I'm not up to digging through the standard at the moment, but if you
    > compile it with "gcc -std=c99 -pedantic-errors" and bugreport the
    > resulting error message, maybe they'll tell you where to find it:)

    gcc has idiotic and inaccurate warning messages [1] (which btw you
    turn into diagnostic errors with -pedantic-errors)
    My program is 100% conforming to C99 (and perhaps C89/POSIX too).

    [1] It correctly warns/errors, however the semantics are incorrect, eg
    says "statement" where "expression" should be used, et cetera.
     
    , Apr 3, 2008
    #9
  10. writes:

    > On Apr 3, 6:47 pm, Hallvard B Furuseth <>
    > wrote:
    >> writes:

    <snip>
    >> > (...) what I demonstrate here is a function taking void *, and
    >> > passing to that function a const char * const.

    >>
    >> void* isn't that magical. You can pass a char* to a void* or
    >> a const char* to a const void*. Not a const char* to a void*.


    > That is not true, and it's not about void *'s "magic". You can also
    > assign a const char * to a char * and still have a conforming
    > program.


    Only because "conforming program" is a rather loose term. A
    conforming program can use non-portable features.

    <snip>
    >> > (...) Here's a perfectly conforming C99 program (...)


    What do you mean by "perfectly conforming"? If you mean the same as
    "strictly conforming", I disagree. Here is the code again:

    #include <stdio.h>
    int foo(void *);
    int main(void) {
    const char * const p = "hello world";
    foo(p);
    return 0;
    }
    int foo(void *p) { return puts(p); }

    >> I'm not up to digging through the standard at the moment, but if you
    >> compile it with "gcc -std=c99 -pedantic-errors" and bugreport the
    >> resulting error message, maybe they'll tell you where to find it:)

    > gcc has idiotic and inaccurate warning messages [1] (which btw you
    > turn into diagnostic errors with -pedantic-errors)
    > My program is 100% conforming to C99 (and perhaps C89/POSIX too).


    Again, what is 100% conforming? It violates a constraint and thus
    requires a diagnostic.

    6.5.2.2 Function calls
    Constraints
    ...
    2 If the expression that denotes the called function has a type that
    includes a prototype, the number of arguments shall agree with the
    number of parameters. Each argument shall have a type such that its
    value may be assigned to an object with the unqualified version of
    the type of its corresponding parameter.

    I.e. the argument, p, must have a type such that its value may be
    assigned to an object of type void *. The correctness of the call is
    defined in terms of the correctness of:

    const char * const arg = "hello world";
    void *param = arg;

    So we got to:

    6.5.16.1 Simple assignment
    Constraints
    One of the following shall hold:

    — the left operand has qualified or unqualified arithmetic type and
    the right has arithmetic type;

    — the left operand has a qualified or unqualified version of a
    structure or union type compatible with the type of the right;

    — both operands are pointers to qualified or unqualified versions of
    compatible types, and the type pointed to by the left has all the
    qualifiers of the type pointed to by the right;

    No to these three.

    — one operand is a pointer to an object or incomplete type and the
    other is a pointer to a qualified or unqualified version of void,
    and the type pointed to by the left has all the qualifiers of the
    type pointed to by the right;

    No, but this is close. One (arg) is a pointer to an object and the
    other (param) is a pointer to an unqualified version of void, but the
    type pointed to by the left (void) does not have all the qualifiers of
    the type pointed to by the right (const char).

    — the left operand is a pointer and the right is a null pointer
    constant; or

    — the left operand has type _Bool and the right is a pointer.

    No for these as well. So gcc is correct in issuing a diagnostic.

    --
    Ben.
     
    Ben Bacarisse, Apr 3, 2008
    #10
  11. Robert Smith

    Bartc Guest

    "Robert Smith" <> wrote in message
    news:rd5Jj.5608$...
    > some of the syntax wasn't overloaded so much...
    >
    > Was just musing that if pointer de-referencing and pointer-to-type had
    > seperate syntax (ie use a character other than '*' for one of them) it
    > would make things much easier to read. You wouldn't get stuff like:
    >
    > pthread_create(&thread, NULL, (void *(*)(void*))ThreadProc, (void
    > *)parameter);


    I've got more serious problems with understanding C declarations, for
    example:

    What on earth does (void *(*)(void*)) mean? It's some sort of cast, so the
    type is:

    void *(*)(void*)

    My guess is it's a function returning type void*, and maybe taking a single
    parameter of void*, but what about the (*) in the middle?!

    And * does apparently seem to change position. Unless I've got these wrong:

    int *a a is pointer to int (* on left)
    (int *) pointer to int (* on right)
    *a dereference pointer to int (* on left again).

    In my case a type declaration that reads linearly from left to right would
    help tremendously, because that's what I'm familiar with. Just having the
    word 'function' in a function declaration would make things so much clearer!

    Maybe C's syntax will get easier with use, I don't know, but since I stay
    well clear of anything complicated, probably not.

    --
    Bart
     
    Bartc, Apr 3, 2008
    #11
  12. Robert Smith

    Ben Pfaff Guest

    "Bartc" <> writes:

    > What on earth does (void *(*)(void*)) mean? It's some sort of cast, so the
    > type is:
    >
    > void *(*)(void*)
    >
    > My guess is it's a function returning type void*, and maybe taking a single
    > parameter of void*, but what about the (*) in the middle?!


    That means it's a pointer to a function. The full type is
    "pointer to function taking a void * argument and returning void
    *".

    > And * does apparently seem to change position. Unless I've got these wrong:
    >
    > int *a a is pointer to int (* on left)


    OK.

    > (int *) pointer to int (* on right)


    That's not a type or a declaration. It's a cast. In a cast,
    there is no variable to name, so "a" is omitted. If there was a
    variable there, it would be in the same position.

    There is one situation where the variable name may be included or
    omitted, at your option, and that is in a function prototype (that
    is not for a function being defined). So the following are
    equivalent, and may be enlightening:
    void foo(int *a);
    void foo(int *);
    See? The variable name is just omitted, and there's no changing
    of position going on.
    --
    int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.\
    \n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
    );while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p\
    );}return 0;}
     
    Ben Pfaff, Apr 3, 2008
    #12
  13. Robert Smith

    Ian Collins Guest

    wrote:
    > On Apr 3, 6:47 pm, Hallvard B Furuseth <>
    > wrote:
    >> writes:
    >>> On Apr 3, 6:17 pm, Hallvard B Furuseth <> wrote:
    >>>>> Even if parameter was const char * const parameter = "hello world";
    >>>>> the cast can still be omitted, as long as ThreadProc does not try to
    >>>>> mutate what is pointed to by parameter.
    >>>> No. pthread_create() takes a void* 3rd parameter. It's an error
    >>>> to assign or pass a "pointer to const" to a "pointer to not-const".
    >>> I don't remember what the POSIX standard says about this, but in C it
    >>> is not.

    >> You are confusing something with something. Half the purpose of the
    >> const qualifier is that the compiler's type checking can help you catch
    >> assignments to read-only objects.

    > Well, that's *your* opinion. My opinion is that const is there for
    > optimization and documentation.


    Well most compilers would agree with Hallvard and not with you.

    Passing a const pointer to a function with a void* parameter is a
    constraint violation and the compiler should issue a diagnostic.

    > Ie foo(const int *) informs the programmer foo shall not modify what
    > is pointed to by its argument.


    True, and foo( int* ) offers no such guarantee, so passing a const int*
    to foo risks foo attempting to modify the data pointer to.

    >>> (...) what I demonstrate here is a function taking void *, and
    >>> passing to that function a const char * const.


    >> void* isn't that magical. You can pass a char* to a void* or
    >> a const char* to a const void*. Not a const char* to a void*.


    > That is not true, and it's not about void *'s "magic". You can also
    > assign a const char * to a char * and still have a conforming program.


    No, you have a constraint violation.

    > Also, while thinking about it, pthread_create shouldn't be able to
    > access what is pointed to by its last argument. Unless POSIX says
    > something about it (and I'm positive it does not) then it's POSIX
    > conforming too.
    >

    Nonsense, what's the point in a parameter a function can't access? Even
    is there was one, how could it be enforced?

    --
    Ian Collins.
     
    Ian Collins, Apr 3, 2008
    #13
  14. Robert Smith

    Ian Collins Guest

    Hallvard B Furuseth wrote:
    > Chris Dollin writes:
    >> Robert Smith wrote:
    >>> pthread_create(&thread, NULL, (void *(*)(void*))ThreadProc, (void
    >>> *)parameter);

    >> Surely either `ThreadProc` is already the right type, in which case
    >> the cast can and should be discarded, or it isn't, in which case
    >> the cast is a bug waiting to manifest and `ThreadProc` should be
    >> fixed.
    >>
    >> Yes?

    >
    > And hopefully 'parameter' is a non-const pointer so the void* cast
    > can be dropped too.
    >
    > The times where you do need to clutter the code with unreadable
    > type casts, it may make sense to typedef the offending type.
    >

    No, all the typedef dose is introduce an alias, it doesn't remove the
    need to cast an inappropriate type.

    If you do need to clutter the code with unreadable casts, you are doing
    something smelly and should reconsider what you are doing.

    --
    Ian Collins.
     
    Ian Collins, Apr 3, 2008
    #14
  15. Robert Smith

    Ian Collins Guest

    Robert Smith wrote:
    > some of the syntax wasn't overloaded so much...
    >
    > Was just musing that if pointer de-referencing and pointer-to-type had
    > seperate syntax (ie use a character other than '*' for one of them) it would
    > make things much easier to read. You wouldn't get stuff like:
    >
    > pthread_create(&thread, NULL, (void *(*)(void*))ThreadProc, (void
    > *)parameter);
    >

    It has already been pointed out that the casts are a smell, but even if
    they were required, C provides typedefs to alias complex type declarations.

    It's a shame typedefs aren't used more often for function pointer types
    in standards. It would make complex function declarations (signal is a
    classic) much easier for a human to parse.

    --
    Ian Collins.
     
    Ian Collins, Apr 3, 2008
    #15
  16. Robert Smith wrote:
    >
    > some of the syntax wasn't overloaded so much...
    >
    > Was just musing that if pointer de-referencing and pointer-to-type had
    > seperate syntax (ie use a character other than '*' for one of them) it would
    > make things much easier to read. You wouldn't get stuff like:
    >
    > pthread_create(&thread, NULL, (void *(*)(void*))ThreadProc, (void
    > *)parameter);


    Aside from what the others said, consider this:

    char *p;

    The use of "*" is consistent, IMO, because:

    "p" is of type "char *", just like the definition says, and
    "*p" is of type "char", just like the definition says.

    --
    +-------------------------+--------------------+-----------------------+
    | Kenneth J. Brody | www.hvcomputer.com | #include |
    | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------+
    Don't e-mail me at: <mailto:>
     
    Kenneth Brody, Apr 3, 2008
    #16
  17. Robert Smith

    CBFalconer Guest

    wrote:
    >

    .... snip ...
    >
    > Here's a perfectly conforming C99 program
    >
    > #include <stdio.h>
    > int foo(void *);
    > int main(void) {
    > const char * const p = "hello world";
    > foo(p);
    > return 0;
    > }
    > int foo(void *p) { return puts(p); }


    And here is one with one less line, no requirements for exact line
    equivalence, and much more understandable, especially to the
    neophyte.

    #include <stdio.h>

    int foo(void *p) { return puts(p); }

    int main(void) {
    char *p = "hello world";

    foo(p);
    return 0;
    }

    I also added blank lines to separate code segments. I didn't
    install 'static' qualifiers.

    I thought I had eliminated all possible warning, but I got:

    junk.c:6: warning: initialization discards qualifiers from pointer
    target type

    and I am confused. Why? gcc is run through an alias for cc:

    alias cc=gcc -W -Wall -ansi -pedantic -Wwrite-strings -Wfloat-equal
    -gstabs+ -ftrapv -O1

    (I suspect the -Wwrite-strings param).

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.



    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Apr 3, 2008
    #17
  18. Robert Smith

    Bartc Guest

    "Ben Pfaff" <> wrote in message
    news:...
    > "Bartc" <> writes:
    >
    >> What on earth does (void *(*)(void*)) mean? It's some sort of cast, so
    >> the
    >> type is:
    >>
    >> void *(*)(void*)
    >>
    >> My guess is it's a function returning type void*, and maybe taking a
    >> single
    >> parameter of void*, but what about the (*) in the middle?!

    >
    > That means it's a pointer to a function. The full type is
    > "pointer to function taking a void * argument and returning void
    > *".


    OK thanks.

    >> And * does apparently seem to change position. Unless I've got these
    >> wrong:
    >> int *a a is pointer to int (* on left)

    >
    > OK.
    >
    >> (int *) pointer to int (* on right)

    >
    > That's not a type or a declaration. It's a cast. In a cast,
    > there is no variable to name, so "a" is omitted. If there was a
    > variable there, it would be in the same position.


    I agree that the type-declaration scheme /is/ logical when you analyse it,
    it's just difficult to read! Being adept at it does not change that.

    While we're in this fantasy thread, I knocked up this new left-to-right
    easy-to-read syntax for C type declarations. Type-decls are constructed with
    the following symbols (enums and some other stuff left out):

    * Pointer to
    type Type name (built-in or typedef-ed)
    function Optional function indicator
    (...)T Function Takes these params, returns type T
    [] Array of
    [N] Array of N of
    struct{...} Struct of
    struct S{...} Struct S of

    These are written left to right, example:

    *int a,b; a,b are both pointers to int
    function(int,int)float Function taking two int params and returning float
    result
    (int,int)float Same without the 'function'
    [10]char s,t s,t are both 10-char arrays
    [10]*char list Array of pointers to char (array of strings)
    *function(*void)*void Above example
    *(*void)*void Above example without 'function'

    Pros:
    * Easy to read, translates naturally to English
    * Variables sharing same array/pointer properties share the one type-decl(as
    in above examples)
    * The typedef T U statement, in practice may have T and U hopelessly
    intermingled for complex type-decls. With this scheme T and U stay separate.
    * Also type-decls appear in typedefs, var-decls, casts, and function params
    all have the same form

    Cons:
    * Can't mix declaration of variables that have different array/pointer
    attributes (but I think that's a bad idea anyway).

    --
    Bart
     
    Bartc, Apr 3, 2008
    #18
  19. On Apr 3, 4:56 pm, wrote:

    > Well, that's *your* opinion. My opinion is that const is there for
    > optimization and documentation.


    "Const" cannot be used for optimization purposes at all. Your code
    either modifies objects, or it doesn't. The compiler doesn't need
    const qualifiers to see that. But a const qualifier on a pointer does
    _not_ in any way whatsoever guarantee or indicate the the object is
    not modified in some other way.

    The situation is completely different if you use a "const restrict"
    pointer in C99.
     
    christian.bau, Apr 3, 2008
    #19
  20. Robert Smith

    Default User Guest

    CBFalconer wrote:

    > wrote:
    > >

    > ... snip ...
    > >
    > > Here's a perfectly conforming C99 program
    > >
    > > #include <stdio.h>
    > > int foo(void *);
    > > int main(void) {
    > > const char * const p = "hello world";
    > > foo(p);
    > > return 0;
    > > }
    > > int foo(void *p) { return puts(p); }

    >
    > And here is one with one less line, no requirements for exact line
    > equivalence, and much more understandable, especially to the
    > neophyte.
    >
    > #include <stdio.h>
    >
    > int foo(void *p) { return puts(p); }
    >
    > int main(void) {
    > char *p = "hello world";
    >
    > foo(p);
    > return 0;
    > }
    >
    > I also added blank lines to separate code segments. I didn't
    > install 'static' qualifiers.
    >
    > I thought I had eliminated all possible warning, but I got:
    >
    > junk.c:6: warning: initialization discards qualifiers from pointer
    > target type
    >
    > and I am confused. Why? gcc is run through an alias for cc:
    >
    > alias cc=gcc -W -Wall -ansi -pedantic -Wwrite-strings -Wfloat-equal
    > -gstabs+ -ftrapv -O1
    >
    > (I suspect the -Wwrite-strings param).


    I suspect you are right.

    -Wwrite-strings
    When compiling C, give string constants the type "const
    char[length]" so that copying the address of one into a
    non-"const" "char *" pointer will get a warning; when
    compiling C++, warn about the deprecated conversion from
    string constants to "char *". These warnings will help
    you find at compile time code that can try to write into
    a string constant, but only if you have been very
    careful about using "const" in declarations and
    prototypes. Otherwise, it will just be a nuisance; this
    is why we did not make -Wall request these warnings.



    Brian
     
    Default User, Apr 4, 2008
    #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. Norman Ackroyd
    Replies:
    1
    Views:
    567
  2. Kathy Burke
    Replies:
    0
    Views:
    358
    Kathy Burke
    Jul 31, 2003
  3. Raterus
    Replies:
    1
    Views:
    2,276
    Srinivas
    Feb 13, 2004
  4. Mmcolli00 Mom
    Replies:
    2
    Views:
    215
    Mmcolli00 Mom
    Jan 27, 2009
  5. AnnMarie
    Replies:
    8
    Views:
    493
    kaeli
    Nov 21, 2003
Loading...

Share This Page