This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

void pointer behaviour ?

Hi,
I observed a strange behaviour (for me only) of void pointer. I wrote a code to access an integer through void pointer as below:

void *ptr;
int a[2] = {1,2};

ptr = (int *)&a;
ptr++; // This is giving error: Unknown Size

Why the above increment statement is giving error as i already cast the pointer to int type ?

Can anybody help me in understanding this ?

Karthik K.

Parents
  • The type "void" has no size (not size 0, but no defined size at all). p is a pointer to void. The ++ operator increments a pointer by the size of the typed pointed to (not by 1, but by 1 * sizeof(*p)). For a pointer-to-void, there is no size, and thus you can't increment a pointer-to-void. Hence the compiler warning, "Unknown size".

    The cast in the assignment statement does not change the type of p. C is a compiled language with static typing. Types cannot be changed dynamically at run time. All a cast does is temporarily override the type of an expression during evaluation.

    A U8* is often a more useful type for "pointer to anything" than is a void* when you're trying to do pointer arithmetic. A U8 has a sizeof 1, which is what most people usually expect for "generic" pointer math. The ANSI void type can be assigned a value of any pointer type, but the type itself can be manipulated only in limited ways.

Reply
  • The type "void" has no size (not size 0, but no defined size at all). p is a pointer to void. The ++ operator increments a pointer by the size of the typed pointed to (not by 1, but by 1 * sizeof(*p)). For a pointer-to-void, there is no size, and thus you can't increment a pointer-to-void. Hence the compiler warning, "Unknown size".

    The cast in the assignment statement does not change the type of p. C is a compiled language with static typing. Types cannot be changed dynamically at run time. All a cast does is temporarily override the type of an expression during evaluation.

    A U8* is often a more useful type for "pointer to anything" than is a void* when you're trying to do pointer arithmetic. A U8 has a sizeof 1, which is what most people usually expect for "generic" pointer math. The ANSI void type can be assigned a value of any pointer type, but the type itself can be manipulated only in limited ways.

Children
  • Sorry a bit off subject. I find that the Realview compiler wobbles if I try to use U8. Is there a U16 and S8, S16?

    typedef unsigned char U8;
    typedef unsigned short U16;

    This works. But I seem to have seen U8 mentioned in the release notes somewhere as a new feature, or am I hallucinating. I had forgotten about it until I read this post.

  • "I find that the Realview compiler wobbles if I try to use U8."

    I don't understand what "wobbles" means in this context.

    "Is there a U16 and S8, S16?"

    I think you'll find that toolchains typically do not define the above-mentioned types and leave that for the user if they want. Forward looking toolchains (forward to C99, that is) might define something similar using the 'intn_t exact-width integer types.

  • My mistake, from the post I had the impression that U8 etc should be available without resorting to :-

    typedef unsigned char U8;

    But from what you say, I shouldn't expect them to be defined. Just had that funny feeling that I had read it in a Keil update somewhere.

    Thanks.

  • "U8" isn't an official C type. But every C programmer I know has adopted some similar local convention for naming types with explicit widths. Often you see UINT8. Some people like BYTE.

    C99 introduced new headers, inttypes.h and stdint.h, with official names for these types as well as new "half-open" types. So, you could use "uint8_t" to be modern and official.

    (I may be too stuck in my old rut to switch, and never liked the ANSI _t, for that matter. I already know it's a type from the syntax, thank you; that's why it's in typedef and comes right before the variable...)

    A "half-open" type is one where the compiler has some freedom to choose the representation, under some constraint. For example, there's uint_least16_t and uint_fast16_t. The former is any unsigned in the compiler likes so long as it has at least 16 bits. This type is useful for such things as loop counters, where you know you have to be able to count to a certain value, but otherwise don't care about the width. The _fastN types specify the fastest representation with at least N bits. These types leave the compiler some flexibility to optimize while still letting the programmer guaranteed needed sizes.

    For structures that represent hardware or message formats, you'll still want the absolute, fixed size types like int16_t.

    The C99 headers also have lots of useful macros and types for dealing with common problems: min and max integer values, making sure literals are a particular bit width, correct pointer arithmetic types and bounds, and so on.

    I'd like to see Keil introduce header files with support for these types on the way to C99 compliance.

  • Thanks Drew, I am new to C and forum posts such as this void pointer one help me learn. I searched the web for C99 and did find some examples so at least understand what it is. I will use some bits of it from now on. But at my present level of C knowlewdge will not try to do more than this.

    I am struggling with multi-dimensional char arrays, pointer etc right now and am getting some odd results, but I will persevere!

  • "persevere!",

    HOW loong can you persevere without the chip indicating ANYthing,
    red or green or any thing on the led?

  • "I am new to C ... I am struggling with multi-dimensional char arrays, pointer etc"

    You might find it easier to get to grips with such issues on a PC; then, once you've mastered the language, you can move on to applying it in the specialist world of embedded microcontrollers...

  • Your right, but I like to see things happening! I do know assembly fairly well, and have used Forth for embedded. In fact I compared Arm Forth to Keil, but decided to go with C because I wanted to broaden my horizon and I have the opportunity (time) to do it.

  • " but I like to see things happening! "

    yaaa, but your chip may not get 'signal' iN the Target Board, and could be 'signal' problem or Power not ON.
    Have you checked?