undefined behavior or not undefined behavior? That is the question

Discussion in 'C Programming' started by Mantorok Redgormor, Feb 8, 2004.

  1. #include <stdio.h>

    struct foo { int example; struct bar *ptr; };

    int main(void)
    {
    struct foo baz;
    baz.ptr = NULL; /* Undefined behavior? */

    return 0;
    }


    My second question is not related to undefined behavior.
    I read that bitwise AND is equivalent to
    "Multiplication modulus two" They made some notation
    with something that looked like two Zs'

    Anyone familiar with that?

    However:

    printf("%d\n", 10 & 42);

    printf("%d\n", (10 * 42) % 2);

    most certainly differ.

    but they used ^ for AND and said:

    a * b (mod 2) = a ^ b
     
    Mantorok Redgormor, Feb 8, 2004
    #1
    1. Advertisements

  2. first of all define struct bar nad #include <stdlib.h>

    why should assignment of a pointer to NULL should be undefined
    I don't think this is right... Am I missing something?
    the ^ is not AND operator, it is the XOR operator...
    and it doesn't seem to work either...

    --
    #include <stdio.h>
    #define p(s) printf(#s" endian")
    int main(void){int v=1;*(char*)&v?p(Little):p(Big);return 0;}

    Giannis Papadopoulos
    http://dop.users.uth.gr/
    University of Thessaly
    Computer & Communications Engineering dept.
     
    Papadopoulos Giannis, Feb 8, 2004
    #2
    1. Advertisements

  3. Unnecessary and unnecessary, respectively. A definition for
    'struct bar' is not needed in order to declare a pointer to said
    Who knows /what/ was running through Mantorok's head? [To
    the OP: Why not /tell/ us why you think such-and-such should be
    undefined, or defined, rather than just posting a random text
    file and letting us run it through a compiler for you? How do
    you expect to learn anything this way?]

    Yes, but I have no idea what, because, like the OP, you didn't
    give any reasons for your statement that you "don't think this
    is right."
    Bitwise AND is exactly isomorphic to multiplication in the
    field of the integers modulo 2. Compare:

    0 & 0 = 0 0 * 0 = 0
    0 & 1 = 0 0 * 1 = 0
    1 & 0 = 0 1 * 0 = 0
    1 & 1 = 1 1 * 1 = 1

    See? Same thing.

    Do you mean "they" (perhaps a math textbook?) used the
    logical AND operator, looking something like an upside-down wide V,
    or the exponentiation operator "up-arrow," displayed on a computer
    screen as "^"?
    In C, logical AND is spelled &&, exponentiation is spelled "pow"
    (after #including <math.h>), and the operator spelled ^ is pronounced
    "bitwise XOR."

    [sig includes]
    Oh yeah, and that code isn't c.l.c-compliant. :) [ISO standard
    C doesn't really give any useful definitions regarding endianness,
    nor does it guarantee that the attempted evaluation of *(char*)&v
    won't invoke undefined behavior on the DeathStation 9000.]

    -Arthur
     
    Arthur J. O'Dwyer, Feb 8, 2004
    #3
  4. Hmm, whenever I used NULL, I used it with malloc() calls.. So I thought
    they were both in stdlib.h...
    Maybe for 1 and 0 (as integers)... elsewhere is unapplicable...
    I am only trying to find if the machine is big endian or little endian..
    After 0.29 s in google I found
    http://www.treedragon.com/ged/fe/no/endianess.htm

    And why should *(char*)&v invoke undefined behaviour? I am only doing this

    union {
    int v;
    char c[4]; /* assuming 32-bit machine */
    };

    So v in big endian is 0x00 0x00 0x00 0x01 and in little endian is 0x01
    0x00 0x00 0x00.

    Using c[0] (or equivalently *(char*)&v) one can find endianess.. Still,
    this doesn't work on machines with 8-bit integers...


    --
    #include <stdio.h>
    #define p(s) printf(#s" endian")
    int main(void){int v=1;*(char*)&v?p(Little):p(Big);return 0;}

    Giannis Papadopoulos
    http://dop.users.uth.gr/
    University of Thessaly
    Computer & Communications Engineering dept.
     
    Papadopoulos Giannis, Feb 8, 2004
    #4
  5. Mantorok Redgormor

    Malcolm Guest

    NULL is defined in lots of headers for convenience.
    The answer is that there might be trap representations. For instance, a
    Communist computer manufacturer could declare the numer 36 to be an illegal
    representation. Every time the computer detects it, it could abort with an
    error "Capitalist user detected".
    No you are not. Unions are designed to save space, but there is guarantee
    about layout. I don't actually know any trap architectures, but probably the
    layout would be as you say, and a trap would result as you illegally access
    a char after writing an int.
     
    Malcolm, Feb 8, 2004
    #5
  6. Mantorok Redgormor

    pete Guest

    They are both in stdlib.h. All of the macros,
    which are needed to describe any standard library function,
    are defined in the header corresponding to the function.
    Therefore, all standard library headers which have the prototype
    for any function capable of returning NULL, define NULL too.
    malloc takes a size_t argument,
    so you can assume that size_t is defined in stdlib.h, also.
    There's also the possibility of mixed endian.
    There are none in C.
    type int, has exactly 1 sign bit and at least 15 value bits, always.
    We don't generally assume a 32 bit machine, here.
    If int has any padding, it's possible that *(char*)&v
    might be signed and also a trap representation of negative zero.
     
    pete, Feb 8, 2004
    #6
  7. Mantorok Redgormor

    CBFalconer Guest

    Why should he? That is a serious question. He doesn't need
    stdio.h either.
     
    CBFalconer, Feb 8, 2004
    #7
  8. well if an lvalue does not designate an object
    then it invokes undefined behavior.

    you need type information for a type to not be
    an incomplete type.

    until then, the type of something is incomplete and
    does not refer to an object, right?

    so when you have a struct declaration of:

    struct foo { int example; struct bar *ptr; };

    and then supply your definition:

    struct foo baz;

    baz is an actual object, example is an actual object
    but what about "ptr" ? it is not a valid pointer object
    right?

    so it cannot hold:

    baz.ptr = NULL; /* can't hold the value of NULL? */

    and also under such a circumstance, why is this even
    allowed in this regard?

    If the type definition is never given for "struct bar"
    then the type may never be completed
    so in essence you end up with a completely useless
    incomplete type in this regard.

    it would seem logical for a compiler
    to have to issue some type of diagnostic
    if it knows the type is never completed.
    yeah, sorry. I was thinking modulus % operator
    when what it meant was in base2.

     
    Mantorok Redgormor, Feb 8, 2004
    #8
  9. Mantorok Redgormor

    Leor Zolman Guest

    Note how you switched terminology when you got to "ptr"? If you'd gone
    on to say, "...it is not an actual object, right"? You'd have been
    wrong, because it is. But it is not a valid pointer.

    For a pointer,
    SOMETHING *p;
    p can represent an lvalue, and so can *p. But they're distinct.
    -leor


    Leor Zolman
    BD Software

    www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
    C++ users: Download BD Software's free STL Error Message
    Decryptor at www.bdsoft.com/tools/stlfilt.html
     
    Leor Zolman, Feb 8, 2004
    #9
  10. Mantorok Redgormor

    Malcolm Guest

    Though I once had a small embedded system that worked on 8-bit ints, so the
    requirements of the standard and actual practise don't always match.
     
    Malcolm, Feb 8, 2004
    #10
  11. Mantorok Redgormor

    Joe Wright Guest

    Hello Leor. Welcome to the fray. I remember you as the author of BDS C
    for CP/M 80 a quarter century ago. Or is it only 20 years? Or do I have
    you mixed up with the other Leor Zolman? :)
     
    Joe Wright, Feb 8, 2004
    #11
  12. Any implementation that has CHAR_BIT == 8 has 8-bit integers. No C
    implementation is *required* to have 8-bit integers, but any *may*. That
    no flavor of int can fit into 8 bits is a red herring.
    It is also false thatYour implementation does not define the C language.
     
    Martin Ambuhl, Feb 8, 2004
    #12
  13. Mantorok Redgormor

    Malcolm Guest

    To an extent it does. If the term "C" is used to refer to the language, then
    that become part of the meaning of the term. Of course the implementation is
    not part of the formal, ANSI definition of the language, but even ANSI
    cannot successfully define C because they cannot force implemetation of
    their standards :)
     
    Malcolm, Feb 8, 2004
    #13
  14. Mantorok Redgormor

    Leor Zolman Guest

    You must mean my evil anti-matter twin; This Leor only codes ANSI/ISO
    C (always including all conceivable headers), and wouldn't be caught
    dead _using_ a compiler that treats all externs like a single unnamed
    FORTRAN common block and lacks initialization, longs or floats, let
    alone _writing_ one...
    -leor #2

    P.S. Exactly 25 years ago, Leor #1 was about 1/2-way through coding
    the first version of BDS C; it passed its first serious test,
    compiling and running the Othello program he had gotten sick of trying
    to hand-convert into 8080 assembly language, in early April of '79.

    P.P.S. If you meant to send that post as a personal email. _please_
    don't tell me... ;-)



    Leor Zolman
    BD Software

    www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
    C++ users: Download BD Software's free STL Error Message
    Decryptor at www.bdsoft.com/tools/stlfilt.html
     
    Leor Zolman, Feb 8, 2004
    #14
  15. But is NULL defined in stdio.h as mr. O' Dwyer suggested?
    It just checks if the first byte of an int is 0 or anything else.. If it
    is zero, it is a big endian machine, else a little endian..

    And I am not assuming that it is a 32-bit machine.. I am only using the
    first byte.. So being 32-bit or 64-bit is irrelevant...


    --
    #include <stdio.h>
    #define p(s) printf(#s" endian")
    int main(void){int v=1;*(char*)&v?p(Little):p(Big);return 0;}

    Giannis Papadopoulos
    http://dop.users.uth.gr/
    University of Thessaly
    Computer & Communications Engineering dept.
     
    Papadopoulos Giannis, Feb 8, 2004
    #15
  16. It was probably in a text using mathematical notation. It is
    equivalent to pointwise multiplication in an n-dimensional
    vector space over Z_2. Or (to be more precise) an operation
    from Z_2<sup>n * Z_2<sup>n -> Z_2<sup>n (where _ means subscript
    Not in mathematical notation. There ^ indicates AND. How ^
    came to be XOR in C is interesting, because it is AND in the
    Algol languages.
     
    Dik T. Winter, Feb 9, 2004
    #16
  17. I think you missed something.
    "ptr" can never be an object since
    its type definition is never complete.

    so it remains an incomplete type.

    though I can't find the relevant sections in the standard
    that say that at this time.



    --
    nethlek
     
    Mantorok Redgormor, Feb 9, 2004
    #17
  18. Mantorok Redgormor

    Leor Zolman Guest

    The point I was trying to make is that "ptr", being a pointer, is
    itself just like a "primitive type". It cannot be incomplete. However,
    it can be defined to /point/ to something whose type is still
    incomplete at the time of ptr's definition.
    "struct bar" is the incomplete type, /not/ ptr.
    Just /think/ about it. Doesn't the compiler have all the information
    it needs to place ptr into a fixed location in memory of known size?
    It is the size of a pointer; whatever that is, it is /known/.
    -leor
     
    Leor Zolman, Feb 9, 2004
    #18
  19. Nitpick: I would have said it was an operation *from*
    (Z_2)^n * (Z_2)^n *to* (Z_2)^n, or an operation *in*
    (Z_2)^n * (Z_2)^n -> (Z_2)^n. I don't know if that's a widely
    used mode of speech, but it makes more sense to me, syntactically
    speaking.
    As I said (and you snipped), ^ in mathematics quite often
    indicates exponentiation, and *never* logical AND. The usual
    symbol for logical AND is a sort of inverted V, as seen here:
    http://mathworld.wolfram.com/aimg1694.gif
    which is not the same symbol as the caret or up-arrow, as seen here:
    "A ^ B"
    Well, okay, I couldn't find any images of that symbol. But you
    can get both of them in LaTeX with \land and \^{}, respectively.

    Same objection as above. The Algol language described in the one
    book I own on the subject uses the inverted-V AND operator seen in
    the image above, IIRC.
    Incidentally, the mathematical symbol for XOR is often a plus sign
    with a circle around it, to indicate that it behaves like addition
    in the field (Z_2)^n. I have no idea where the idea of using ^ for
    XOR came from, except that ^ kind of looks like the lower half of a
    superscript "X". :)

    -Arthur
     
    Arthur J. O'Dwyer, Feb 9, 2004
    #19
  20. ....
    It would seem to be C99 complient. [Even if the output won't necessarily be
    meaningful.]
     
    Peter Nilsson, Feb 9, 2004
    #20
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.