Why compiler not generating any warning ?

Discussion in 'C Programming' started by junky_fellow@yahoo.co.in, Jun 3, 2005.

  1. Guest

    Consider the following piece of code:

    struct junk {
    int i_val;
    int i_val1;
    char c_val;
    };

    int main(void)
    {
    struct junk str_junk;
    int * i_ptr;
    struct junk * pstr_junk;
    pstr_junk = &str_junk;
    i_ptr = (int *)pstr_junk + 1; /* shouldn't the compiler
    give warning here ? */
    }

    On compiling this program: cc -c99 -check -portable test.c
    I don't get any warning.
    However, the statement
    i_ptr = (int *)pstr_junk + 1; seems to be incorrect to me.

    Here, pstr_junk is a pointer to structure and it is being typecasted to
    "int *" which may cause undefined behaviour.
    But on compilation I don't get any warning message.
    So, what is the way to cacth these type of bugs ? Is there
    any other tool that may find out all undefined, unportable
    behaviour ?
    I tried *lint* as well but it also didn't warned for this.

    Only, the typecasting to "char *" should be allowed which is
    *guaranteed* to point to the lowest addressed byte of the structure.
     
    , Jun 3, 2005
    #1
    1. Advertising

  2. pete Guest

    wrote:

    > But on compilation I don't get any warning message.
    > So, what is the way to cacth these type of bugs ?


    Learn more C.

    --
    pete
     
    pete, Jun 3, 2005
    #2
    1. Advertising

  3. -berlin.de Guest

    wrote:
    > Consider the following piece of code:


    > struct junk {
    > int i_val;
    > int i_val1;
    > char c_val;
    > };


    > int main(void)
    > {
    > struct junk str_junk;
    > int * i_ptr;
    > struct junk * pstr_junk;
    > pstr_junk = &str_junk;
    > i_ptr = (int *)pstr_junk + 1; /* shouldn't the compiler
    > give warning here ? */
    > }


    > On compiling this program: cc -c99 -check -portable test.c
    > I don't get any warning.
    > However, the statement
    > i_ptr = (int *)pstr_junk + 1; seems to be incorrect to me.


    > Here, pstr_junk is a pointer to structure and it is being typecasted to
    > "int *" which may cause undefined behaviour.


    You will also get undefined behaviour when you write past the end of
    an array, if you use a pointer to already deallocated memory etc. ect.
    but the compiler won't warn about that.

    > But on compilation I don't get any warning message.


    Well, you tell the compiler "convert this pointer to a pointer of
    a different type". So the compiler does, and since you explicitely
    told it to do that why should it doubt the wisdom of your commands?
    If you cast you basically say "I know what I am doing, don't tell
    me I shouldn't, if I would like you to warn me I wouldn't use that
    [expletive censored] cast". And afterwards you tell it "assign to
    a pointer from a pointer of the same type" which is 100% legal and
    not dangerous at all.

    > So, what is the way to cacth these type of bugs ? Is there
    > any other tool that may find out all undefined, unportable
    > behaviour ?


    The best tool is probably between your ears;-) View all casts as
    being suspicious until you're satisifed that they are ok. Finding
    all instances of undefined behaviour would be impossible, it might
    only happen at runtime - the compiler can't typically know in ad-
    vance if e.g. in an access of an array element the index is going
    to be within the bounds of the array. And undefined behaviour is
    not something evil in itself, it's just something the C standard
    does not define. And in most programs you actually rely on unde-
    fined behaviour to work out fine, e.g. when you call a function
    in a third-party library - while a strictly conforming program may
    use only those features of the language and library specified in
    the C standard you very often need more than just that.

    > Only, the typecasting to "char *" should be allowed which is
    > *guaranteed* to point to the lowest addressed byte of the structure.


    In this case maybe yes. But there can be situations where you
    know what's going to happen on the platform you're working on
    (because it's well-documented) and where you have to explicitely
    invoke undefined behaviour in order to get things done.

    Regards, Jens
    --
    \ Jens Thoms Toerring ___ -berlin.de
    \__________________________ http://www.toerring.de
     
    -berlin.de, Jun 3, 2005
    #3
  4. jacob navia Guest

    pete wrote:
    > wrote:
    >
    >
    >>But on compilation I don't get any warning message.
    >>So, what is the way to cacth these type of bugs ?

    >
    >
    > Learn more C.
    >

    What is the point of this reply?

    He is exactly trying to learn more C and asks in this
    discussion group a question.

    Of course *you* never asked any questions when you were learning C.

    Why being rude to newcomers?

    If you do not feel like answering or you think the question is silly
    just do not reply.

    jakob
     
    jacob navia, Jun 3, 2005
    #4
  5. pete Guest

    jacob navia wrote:
    >
    > pete wrote:
    > > wrote:
    > >
    > >
    > >>But on compilation I don't get any warning message.
    > >>So, what is the way to cacth these type of bugs ?

    > >
    > >
    > > Learn more C.
    > >

    > What is the point of this reply?


    The only way that you catch undefined behavior
    that your compiler warnings miss, is by knowing enough C.
    That's pretty much the whole point of reading this newsgroup.

    --
    pete
     
    pete, Jun 3, 2005
    #5
  6. Ed Vogel Guest

    <> wrote in message
    > On compiling this program: cc -c99 -check -portable test.c
    > I don't get any warning.
    > However, the statement
    > i_ptr = (int *)pstr_junk + 1; seems to be incorrect to me.
    >
    > Here, pstr_junk is a pointer to structure and it is being typecasted to
    > "int *" which may cause undefined behaviour.
    > But on compilation I don't get any warning message.


    From the switches used, I'll guess you're using the HP C compiler
    on Tru64. If that's the case, you can get the compiler to
    emit a diagnostic for this case.

    Using -check enables most messages, but not all. To enable
    all messages use the -msg_enable all option. To get the
    specific message for this case, use -msg_enable ansialiascast.

    Ed Vogel
    HP/Compaq/DEC C/C++ Engineering
     
    Ed Vogel, Jun 3, 2005
    #6
  7. On Fri, 03 Jun 2005 04:03:17 -0700, junky_fellow wrote:
    > Consider the following piece of code:
    >
    > struct junk {
    > int i_val;
    > int i_val1;
    > char c_val;
    > };
    >
    > int main(void)
    > {
    > struct junk str_junk;
    > int * i_ptr;
    > struct junk * pstr_junk;
    > pstr_junk = &str_junk;
    > i_ptr = (int *)pstr_junk + 1; /* shouldn't the compiler
    > give warning here ? */
    > }
    >
    > On compiling this program: cc -c99 -check -portable test.c I don't get
    > any warning.
    > However, the statement
    > i_ptr = (int *)pstr_junk + 1; seems to be incorrect to me.
    >
    > Here, pstr_junk is a pointer to structure and it is being typecasted to
    > "int *" which may cause undefined behaviour.


    You can safely convert a pointer to a structure to a pointer to the first
    element of the structure, no undefined behavior. What is dangerous is the
    pointer arithmetic you perform after the conversion. You might expect
    i_ptr to point to the second member in the structure but since there may
    be padding between the two integers, dereferencing the pointer would
    invoke UB.

    > But on compilation I don't get any warning message.


    I don't see anything that requires such a message.

    > So, what is the way to cacth these type of bugs ? Is there any other
    > tool that may find out all undefined, unportable behaviour ?


    Nothing to add to pete and Jens responses.

    > I tried *lint* as well but it also didn't warned for this.


    Okay.

    > Only, the typecasting to "char *" should be allowed which is
    > *guaranteed* to point to the lowest addressed byte of the structure.


    Nope. In addition to this and the case I described above, a pointer to a
    structure may safely be converted to a pointer to any other structure and
    back again.

    Robert Gamble
     
    Robert Gamble, Jun 3, 2005
    #7
  8. > struct junk str_junk;
    > int * i_ptr;
    > struct junk * pstr_junk;
    > pstr_junk = &str_junk;
    > i_ptr = (int *)pstr_junk + 1; /* shouldn't the compiler
    > give warning here ? */


    Why? You casted pstr_junk to an integer pointer. Since you are doing
    an explicit cast, the compiler assumes that you know what you are doing.
    Then you told the integer pointer to advance one, which is a perfectly
    valid thing for an integer pointer to do (though, because it's from the
    cast, the results are undefined, but since you did an explicit cast, the
    compiler won't complain). Then you assigned your new integer pointer to
    i_ptr, which is of type int *.

    What did you expect the compiler to complain about?

    Jon
    ----
    Learn to program using Linux assembly language
    http://www.cafeshops.com/bartlettpublish.8640017
     
    Jonathan Bartlett, Jun 3, 2005
    #8
  9. On 3 Jun 2005 04:03:17 -0700, in comp.lang.c ,
    wrote:

    >However, the statement
    >i_ptr = (int *)pstr_junk + 1; seems to be incorrect to me.


    it /is/ incorrect. But you lied to the compiler, by putting in the
    cast. This says "shut up, I know what I'm doing" to the compiler.
    Hence no warning.

    >So, what is the way to cacth these type of bugs ?


    Avoid casts, which are almost never needed in C, unless you're trying
    to do naughty things. Or programme better...

    >I tried *lint* as well but it also didn't warned for this.


    It can't since you already lied and told us that you knew what you
    were doing....

    >Only, the typecasting to "char *" should be allowed which is
    >*guaranteed* to point to the lowest addressed byte of the structure.


    You need to understand the difference between a conversion and a cast.

    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

    ----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
     
    Mark McIntyre, Jun 3, 2005
    #9
  10. On Fri, 03 Jun 2005 12:42:44 GMT, in comp.lang.c , pete
    <> wrote:

    >jacob navia wrote:
    >>
    >> pete wrote:
    >> > wrote:
    >> >
    >> >
    >> >>But on compilation I don't get any warning message.
    >> >>So, what is the way to cacth these type of bugs ?
    >> >
    >> >
    >> > Learn more C.
    >> >

    >> What is the point of this reply?

    >
    >The only way that you catch undefined behavior
    >that your compiler warnings miss, is by knowing enough C.
    >That's pretty much the whole point of reading this newsgroup.


    To be fair though, you could have explained *why* the compiler didn't
    grumble, and why using casts is a bad idea.

    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

    ----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
     
    Mark McIntyre, Jun 3, 2005
    #10
  11. CBFalconer Guest

    wrote:
    >

    .... snip ...
    > i_ptr = (int *)pstr_junk + 1; /* shouldn't the compiler
    > give warning here ? */


    Why? You used a cast, which said specifically "I know what I am
    doing and don't harass me about it". You can always add 1 to a
    pointer, but the result may not be useful.

    Casts are usually a sign of an error.

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
     
    CBFalconer, Jun 3, 2005
    #11
  12. -berlin.de Guest

    CBFalconer <> wrote:
    > wrote:
    >>

    > ... snip ...
    >> i_ptr = (int *)pstr_junk + 1; /* shouldn't the compiler
    >> give warning here ? */


    > Why? You used a cast, which said specifically "I know what I am
    > doing and don't harass me about it". You can always add 1 to a
    > pointer, but the result may not be useful.


    > Casts are usually a sign of an error.


    May I qualify this a bit? I would say that using casts in programs
    that are supposed to be portable are, if not a sign of an error,
    often a sign of either bad design or a sign of misunderstandings.
    On the other hand, in programs - and there are a lot in the wild,
    and I have to admit that I am guilty of writing my share of them
    - where you deliberately invoke undefined behaviour to get things
    done (e.g. in device drivers and other programs for e.g. directly
    accessing hardware), casts may be the only way to go and, when used
    while being aware of what they do they are not necessarily evil.
    Since 'junky_fellow' seems to be on a quest of finding out where
    what makes sense and what's a stupid idea I think he has some right
    to get the real gray-scale picture and not just the black-and-white
    view of the world;-)
    Regards, Jens
    --
    \ Jens Thoms Toerring ___ -berlin.de
    \__________________________ http://www.toerring.de
     
    -berlin.de, Jun 3, 2005
    #12
  13. On Fri, 03 Jun 2005 10:13:21 -0400, Jonathan Bartlett
    <> wrote:

    >> struct junk str_junk;
    >> int * i_ptr;
    >> struct junk * pstr_junk;
    >> pstr_junk = &str_junk;
    >> i_ptr = (int *)pstr_junk + 1; /* shouldn't the compiler
    >> give warning here ? */

    >
    >Why? You casted pstr_junk to an integer pointer. Since you are doing
    >an explicit cast, the compiler assumes that you know what you are doing.
    > Then you told the integer pointer to advance one, which is a perfectly
    >valid thing for an integer pointer to do (though, because it's from the
    >cast, the results are undefined, but since you did an explicit cast, the


    Why do you think this is undefined. After the cast, the intermediate
    value must point to str_junk.i_val (which you omitted from your quoted
    material). Incrementing this value by one points to the byte
    immediately after this int (and still well within the struct) which is
    perfectly legal as long as it is not dereferenced.

    >compiler won't complain). Then you assigned your new integer pointer to
    >i_ptr, which is of type int *.
    >
    >What did you expect the compiler to complain about?
    >
    >Jon
    >----
    >Learn to program using Linux assembly language
    >http://www.cafeshops.com/bartlettpublish.8640017




    <<Remove the del for email>>
     
    Barry Schwarz, Jun 4, 2005
    #13
  14. Guest

    I thank you all for your answers. From the various replies in this
    thread what I concluded is that:

    1) One should aviod using casts while writing a program that is
    supposed to be portable. casts are sign of bad design.

    2) Sometimes while writing a piece of code that has to
    directly access h/w (device drivers, embedded s/w) casts may be
    the only option. In such cases, one must be aware of the consequences
    of typecasting. Also, in such cases code review is the best
    tool to find out such bugs. Compiler may not be issuing the
    warning for all such *incompatible* casts.

    Still I have one question. I might sound irritating but its better to
    ask. Please bear with me. As most of you said that the compiler
    didn't generate any warning because it was explicitly told to do
    so. But there are other cases as well where explicit cast is done,
    still the complier gives the warning.
    eg.
    int main(void) {
    char * c_ptr;
    int * i_ptr;
    (int *)i_ptr = (char *) c_ptr; /* warning for this line */
    return(0);
    }

    compiling this code always generates warning.
     
    , Jun 4, 2005
    #14
  15. writes:
    > I thank you all for your answers. From the various replies in this
    > thread what I concluded is that:
    >
    > 1) One should aviod using casts while writing a program that is
    > supposed to be portable. casts are sign of bad design.
    >
    > 2) Sometimes while writing a piece of code that has to
    > directly access h/w (device drivers, embedded s/w) casts may be
    > the only option. In such cases, one must be aware of the consequences
    > of typecasting. Also, in such cases code review is the best
    > tool to find out such bugs. Compiler may not be issuing the
    > warning for all such *incompatible* casts.


    That sounds about right.

    > Still I have one question. I might sound irritating but its better to
    > ask. Please bear with me. As most of you said that the compiler
    > didn't generate any warning because it was explicitly told to do
    > so. But there are other cases as well where explicit cast is done,
    > still the complier gives the warning.
    > eg.
    > int main(void) {
    > char * c_ptr;
    > int * i_ptr;
    > (int *)i_ptr = (char *) c_ptr; /* warning for this line */
    > return(0);
    > }
    >
    > compiling this code always generates warning.


    It might be helpful to mention what the warning says, but ...

    Both the casts are no-ops; they convert a value of a given type to
    that same type. If you're getting a warning about incompatible
    pointer types, it has nothing to do with the casts. You'd get the
    same warning without them.

    But the most important point is that the assignment is illegal (though
    some compilers may allow it as an extension). A cast is not an
    lvalue, and cannot appear on the left side of an assignment, any more
    than you can assign

    x + 1 = 3;

    If you invoke your compiler in conforming mode, it should reject the
    assignment.

    --
    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, Jun 4, 2005
    #15
  16. -berlin.de Guest

    wrote:
    > 1) One should aviod using casts while writing a program that is
    > supposed to be portable. casts are sign of bad design.


    Let's be a bit more pedantic and restrict that to pointer casts.
    Casting "normal" values is quite common, you may often see in C89
    programs e.g.

    char hw[ ] = "Hello world!";
    printf( "%lu\n", ( unsigned long ) strlen( hw );

    to convert the size_t type return value of strlen() to something you
    can print with one of the available format specifier (in C99 you bet-
    ter would drop the cast and use "%zu" in the format string instead) or

    double d = 42.1234;
    int i = ( int ) d;

    to assign the integer part of 'd' to 'i', snipping off the fractional
    part.

    And while casting pointers is often a sign of some trouble in a program,
    there exist a few cases where they it's actually required, mostly in
    conjunction with arguments of variadic functions. Take the following
    (admittedly rather contrived) example program:

    #include <stdio.h>
    #include <stdarg.h>

    double add_to( double stuff, ... )
    {
    va_list ap;
    double *dp;

    va_start( ap, stuff );
    while ( ( dp = va_arg( ap, double * ) ) != NULL )
    stuff += *dp;
    va_end( ap );

    return stuff;
    }

    int main( void )
    {
    double d0 = 1.0,
    d1 = 2.0;

    printf( "%f\n", add_to( 0, &d0, ( double * ) NULL ) );
    printf( "%f\n", add_to( 0, &d0, &d1, ( double * ) NULL ) );
    return 0;
    }

    The add_to() function takes a double argument plus an unspecified num-
    ber of double pointers and then adds all the values the pointers are
    pointing to to the first argument, returning the result. The end of
    the argument list is marked by a NULL double pointer.

    You may have noticed that I wrote "NULL double pointer" and not just
    "NULL pointer" in the last sentence. That's because a "NULL double
    pointer" could have a different bit representation than e.g. "NULL
    void pointer", and it's simple values in a certain bit representation
    tha get passed to functions. When you have a function foo() which is
    declared as

    void foo( double *dp );

    and you call it like this

    foo( NULL );

    then the compiler knows that foo() expects a double pointer and will
    convert NULL to a value with the correct bit representation for a
    "NULL double pointer" and not the bit representation for e.g. a "NULL
    void pointer" if the representations differ (that's another reason
    why having correct function declarations can be so important).

    But there's a snag with the add_to() function - the compiler doesn't
    know about the types of the arguments following the first one. So
    when calling add_to() the compiler can't help you by automatically
    converting pointers if necessary and it's then your obligation to
    make sure pointers of the correct type get passed to the function.
    And that's why in the call

    add_to( 0, &d0, ( double * ) NULL )

    the NULL pointer actually must be cast - without the cast, the function
    would be called with a value which is the bit representation of a "NULL
    void pointer" and not necessarily the required representation of a "NULL
    double pointer". So this is a place where a pointer cast isn't a mistake
    but required. (Of course, one may argue that a design of that kind is
    bad, but sometimes there may be no better solution.)

    > 2) Sometimes while writing a piece of code that has to
    > directly access h/w (device drivers, embedded s/w) casts may be
    > the only option. In such cases, one must be aware of the consequences
    > of typecasting. Also, in such cases code review is the best
    > tool to find out such bugs. Compiler may not be issuing the
    > warning for all such *incompatible* casts.


    The compiler probably won't issue a warning for whatever cast (except
    for casts of function pointers to object pointers) since a cast tells
    it that you know better - why would you use the cast otherwise?

    > Still I have one question. I might sound irritating but its better to
    > ask. Please bear with me. As most of you said that the compiler
    > didn't generate any warning because it was explicitly told to do
    > so. But there are other cases as well where explicit cast is done,
    > still the complier gives the warning.
    > eg.
    > int main(void) {
    > char * c_ptr;
    > int * i_ptr;
    > (int *)i_ptr = (char *) c_ptr; /* warning for this line */
    > return(0);
    > }
    >
    > compiling this code always generates warning.


    Something must be wrong with your compiler since this shouldn't just
    generate a warning but an error message. You can't use a cast like
    that on the left hand side of the assignment, it's like writing

    int x;
    -x = 3;

    On the left hand side of an assignment you always have to have an ex-
    pression that, when evaluated, must designate an object. And like "-x"
    is not an existing object, so also "(int *) i_ptr" does not designate
    an existing object (the result of the cast is a pointer value, not an
    object). It's not like e.g.

    *( (int *) i_ptr ) = 3;

    where the computed value of the expression designates an object (a
    memory location) a value can be assigned to (at least if 'i_ptr'
    points to some memory you have permission to write to and that the
    alignment requirements are satisfied).

    Let's hope I got that right, otherwise someone more knowledgeable will
    chime in.
    Regards, Jens
    --
    \ Jens Thoms Toerring ___ -berlin.de
    \__________________________ http://www.toerring.de
     
    -berlin.de, Jun 4, 2005
    #16
  17. In article news:,
    wrote:
    [...]
    > of typecasting. Also, in such cases code review is the best
    > tool to find out such bugs. Compiler may not be issuing the
    > warning for all such *incompatible* casts.
    >

    I've taken to creating an include file Cast.h with the following
    #ifndef NO_CAST
    # define CAST(x) (x)
    #else
    # define CAST(x)
    #endif

    Then I create casts as e.g.
    i_ptr = CAST(int*) c_ptr;

    Firstly, one can then simply find all (such) casts in your code by
    searching for CAST(, which is AFAIK impossible when the cast operator is
    just a type in brackets.

    Also simply with #define NO_CAST, all the casts are hidden, and thus the
    compiler highlights all places where casting is required. Then I can
    quickly step through all the warnings to see if the casts I have in
    place are valid.

    I'd welcome feedback from the pro's on whether this is useful, not, or
    just amazingly stupid. :)

    Since casting a integer and a pointer is so different, I've also
    wonderer whether to have two 'operators', INT_CAST() (or
    INTEGRAL_CAST()?) and PTR_CAST(), to allow each form to be
    found/undefined separately...
    --
    Alan J. McFarlane
    http://www.alanjmcf.me.uk/
    Please follow-up in the newsgroup for the benefit of all.
     
    Alan J. McFarlane, Jun 4, 2005
    #17
  18. Ed Vogel Guest

    <-berlin.de> wrote in message
    news:...
    > wrote:
    >> int main(void) {
    >> char * c_ptr;
    >> int * i_ptr;
    >> (int *)i_ptr = (char *) c_ptr; /* warning for this line */
    >> return(0);
    >> }
    >>
    >> compiling this code always generates warning.

    >
    > Something must be wrong with your compiler since this shouldn't just
    > generate a warning but an error message.


    The Standard only requires a diagnostic message. The Standard
    makes no distinction between "error" or "warning" or any other
    type of message.

    Again...assuming the compiler being used is the Compaq C compiler
    on Tru64, the compiler will emit two diagnostics for this program:

    (int *)i_ptr = (char *) c_ptr; /* warning for this line */
    1
    (1) Info: In this statement, the result of the cast "(int ...)i_ptr" is used
    as
    an lvalue. (lvaluecast)

    (1) Warning: In this statement, the referenced type of the pointer value
    "(char
    ....)c_ptr" is "char", which is not compatible with "
    int". (ptrmismatch)

    Ed Vogel
    HP/Compaq/DEC C/C++ Engineering
     
    Ed Vogel, Jun 4, 2005
    #18
  19. Joe Wright Guest

    Keith Thompson wrote:
    > writes:
    >
    >>I thank you all for your answers. From the various replies in this
    >>thread what I concluded is that:
    >>
    >>1) One should aviod using casts while writing a program that is
    >>supposed to be portable. casts are sign of bad design.
    >>
    >>2) Sometimes while writing a piece of code that has to
    >>directly access h/w (device drivers, embedded s/w) casts may be
    >>the only option. In such cases, one must be aware of the consequences
    >>of typecasting. Also, in such cases code review is the best
    >>tool to find out such bugs. Compiler may not be issuing the
    >>warning for all such *incompatible* casts.

    >
    >
    > That sounds about right.
    >
    >
    >>Still I have one question. I might sound irritating but its better to
    >>ask. Please bear with me. As most of you said that the compiler
    >>didn't generate any warning because it was explicitly told to do
    >>so. But there are other cases as well where explicit cast is done,
    >>still the complier gives the warning.
    >>eg.
    >>int main(void) {
    >> char * c_ptr;
    >> int * i_ptr;
    >> (int *)i_ptr = (char *) c_ptr; /* warning for this line */
    >> return(0);
    >>}
    >>
    >>compiling this code always generates warning.

    >
    >
    > It might be helpful to mention what the warning says, but ...
    >

    I get:
    jf.c:4: warning: assignment from incompatible pointer type

    If you really want to do the assignment:
    i_ptr = (int*)c_ptr;
    should work.

    > Both the casts are no-ops; they convert a value of a given type to
    > that same type. If you're getting a warning about incompatible
    > pointer types, it has nothing to do with the casts. You'd get the
    > same warning without them.
    >
    > But the most important point is that the assignment is illegal (though
    > some compilers may allow it as an extension). A cast is not an
    > lvalue, and cannot appear on the left side of an assignment, any more
    > than you can assign
    >
    > x + 1 = 3;
    >
    > If you invoke your compiler in conforming mode, it should reject the
    > assignment.
    >


    Yes. It must reject it. In an assignment, the lvalue is the object, not
    the value it holds. For example:

    int x = 1;
    int y = 2;

    if (x == 1)

    treats the value of x.

    x = y;

    disregards the value of x. In this context x is an object, not a value.

    (int)x = y;

    This must fail because the cast creates a value where an object is required.

    --
    Joe Wright mailto:
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
     
    Joe Wright, Jun 4, 2005
    #19
  20. -berlin.de Guest

    Ed Vogel <> wrote:

    > <-berlin.de> wrote in message
    > news:...
    >> wrote:
    >>> int main(void) {
    >>> char * c_ptr;
    >>> int * i_ptr;
    >>> (int *)i_ptr = (char *) c_ptr; /* warning for this line */
    >>> return(0);
    >>> }
    >>>
    >>> compiling this code always generates warning.

    >>
    >> Something must be wrong with your compiler since this shouldn't just
    >> generate a warning but an error message.


    > The Standard only requires a diagnostic message. The Standard
    > makes no distinction between "error" or "warning" or any other
    > type of message.


    > Again...assuming the compiler being used is the Compaq C compiler
    > on Tru64, the compiler will emit two diagnostics for this program:


    > (int *)i_ptr = (char *) c_ptr; /* warning for this line */
    > 1
    > (1) Info: In this statement, the result of the cast "(int ...)i_ptr" is used
    > as
    > an lvalue. (lvaluecast)


    > (1) Warning: In this statement, the referenced type of the pointer value
    > "(char
    > ...)c_ptr" is "char", which is not compatible with "
    > int". (ptrmismatch)


    Ok, thanks;-)
    Regard, Jens
    --
    \ Jens Thoms Toerring ___ -berlin.de
    \__________________________ http://www.toerring.de
     
    -berlin.de, Jun 4, 2005
    #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. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    979
    Mark Rae
    Dec 21, 2006
  2. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,226
    Smokey Grindel
    Dec 2, 2006
  3. lector
    Replies:
    14
    Views:
    570
    Keith Thompson
    Apr 23, 2008
  4. Anders Koeln
    Replies:
    17
    Views:
    608
    Jorgen Grahn
    Sep 30, 2010
  5. vijendra3mca

    Why does compiler not give warning for this code

    vijendra3mca, Oct 7, 2010, in forum: C Programming
    Replies:
    0
    Views:
    264
    vijendra3mca
    Oct 7, 2010
Loading...

Share This Page