Thread: Retypecasting in C

  1. #16
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by gunner4life View Post
    It is only known at run time. So to implement at element level it would have to be something like this??
    Yes, I think so. I don't see what would be wrong with that.

    I can't promise you anything tho. It is hard to tell why you want to do this; maybe you should explain further.

    For example, what determines whether it is one way or another at runtime? Can it change during runtime? If not, you could define a custom type using if/else
    Code:
    if (condition)
       typedef  myuint uint16;
    else 
       typedef  myuint unint32;
    Then just use (myuint*) in your funcition. You might even be able to redefine a typedef during runtime -- I have never tried.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  2. #17
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by gunner4life View Post
    p++ will give different results for different type of array. I want p++ to automatically increment by element and not by a preset no. of bytes calculated with conditions.
    Moot point. If the pointer is of a particular type, the compiler increments "by element". If you do it by hand, you have to compute the offsets. The only difference is whether the compiler does it or you do it. I wouldn't assume a performance advantage either way, without evidence through testing.


    Quote Originally Posted by gunner4life View Post
    Basically its ok if while accessing its a pointer/array with another name but as an alias to the original array. I hope its not the same thing as accessing through the same name.
    OK; then do this;
    Code:
    uint8 data[2048];
    
    uint16 *data16 = (uint16 *)(&data[0]);
    
    data16[42] = 100;  /*  will treat data[84] and data[85] as if they are collectively a uint16 */
    It is not possible to add an offset to a void pointer: adding an offset to a pointer means knowing the size of whatever is pointed at and a void pointer, by definition, points at something of unknown size.

    Quote Originally Posted by MK27 View Post
    For example, what determines whether it is one way or another at runtime? Can it change during runtime? If not, you could define a custom type using if/else
    Code:
    if (condition)
       typedef  myuint uint16;
    else 
       typedef  myuint unint32;
    Then just use (myuint*) in your funcition. You might even be able to redefine a typedef during runtime -- I have never tried.
    This is not possible. Typedefs only exist at compile time, not at run time.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #18
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by grumpy View Post
    This is not possible. Typedefs only exist at compile time, not at run time.
    Ah...could be done with an #ifdef I think then, depending on the requirements. The OP does say runtime but possibly using two compiled version may work?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #19
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    #ifdef is also compile-time.
    Ifdef with typedef would work as a pair, but only if the conditions were known at compile time.

    Otherwise, the best and perhaps only solution I can think of is to manually do the offset calculation.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #20
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I just have a correction to my first post:
    Code:
    uint8 data[2048];
    uint16 *two = (uint16 *)&data;
    two[42] = 2;
    The second line there shouldn't have had an ampersand:
    Code:
    uint16 *two = (uint16 *)data;
    But enough subsequent posters have said that that it shouldn't be hard to figure out.

    Code:
    if (within limits)
        val = *((uint16 *)void_ptr+offset);
    else
       val = *((uint32 *)void_ptr+offset);
    Yeah, that's pretty much how you have to do it. If you like, you can implement some wrapper functions to make the job easier.
    Code:
    /** Sets data[element] = value, where the size of each element in @a data is given by
        @a size .
    */
    void set(char *data, size_t element, uint32 value, enum element_size_t size) {
        switch(size) {
        case BITS_16:
            ((uint16 *)data)[element] = (uint16)value;
            break;
        case BITS_32:
            ((uint32 *)data)[element] = value;
            break;
        default:
            /* report error */
            break;
        }
    }
    Really, it's not so bad once you add another layer of abstraction.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #21
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    As a note, all this casting from one pointer type to another pointer type only works if the pointer is pointing to somewhere that is correctly aligned for the converted-to type. While this is likely to work on many platforms because of the types involved, it might not work on many platforms if you change to types to, say, an unsigned long long and a short. You can ensure that the variable is at an alignment suitable for both types by:

    1) using malloc/calloc/realloc, which returns a pointer to memory that is suitably aligned for all built-in types
    2) put the variable in a union with another member of the union of the other type

  7. #22
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Sounds like the need to do these weird casts indicates a poor design in general.

Popular pages Recent additions subscribe to a feed