Pointer arithmetic for void pointer in C - c

When a pointer to a particular type (say int, char, float, ..) is incremented, its value is increased by the size of that data type. If a void pointer which points to data of size x is incremented, how does it get to point x bytes ahead? How does the compiler know to add x to value of the pointer?

Final conclusion: arithmetic on a void* is illegal in both C and C++.
GCC allows it as an extension, see Arithmetic on void- and Function-Pointers (note that this section is part of the "C Extensions" chapter of the manual). Clang and ICC likely allow void* arithmetic for the purposes of compatibility with GCC. Other compilers (such as MSVC) disallow arithmetic on void*, and GCC disallows it if the -pedantic-errors flag is specified, or if the -Werror=pointer-arith flag is specified (this flag is useful if your code base must also compile with MSVC).
The C Standard Speaks
Quotes are taken from the n1256 draft.
The standard's description of the addition operation states:
6.5.6-2: For addition, either both
operands shall have arithmetic type,
or one operand shall be a pointer to
an object type and the other shall
have integer type.
So, the question here is whether void* is a pointer to an "object type", or equivalently, whether void is an "object type". The definition for "object type" is:
6.2.5.1: Types are partitioned into object types (types that fully describe objects) , function types (types that describe functions), and incomplete types (types that describe objects but lack information needed to determine their sizes).
And the standard defines void as:
6.2.5-19: The void type comprises
an empty set of values;
it is an incomplete type that cannot
be completed.
Since void is an incomplete type, it is not an object type. Therefore it is not a valid operand to an addition operation.
Therefore you cannot perform pointer arithmetic on a void pointer.
Notes
Originally, it was thought that void* arithmetic was permitted, because of these sections of the C standard:
6.2.5-27: A pointer to void shall have the same representation and alignment
requirements as a pointer to a
character type.
However,
The same representation and alignment
requirements are meant to imply
interchangeability as arguments to
functions, return values from
functions, and members of unions.
So this means that printf("%s", x) has the same meaning whether x has type char* or void*, but it does not mean that you can do arithmetic on a void*.

Pointer arithmetic is not allowed on void* pointers.

cast it to a char pointer an increment your pointer forward x bytes ahead.

The C standard does not allow void pointer arithmetic. However, GNU C is allowed by considering the size of void is 1.
C11 standard §6.2.5
Paragraph - 19
The void type comprises an empty set of values; it is an incomplete
object type that cannot be completed.
Following program is working fine in GCC compiler.
#include<stdio.h>
int main()
{
int arr[2] = {1, 2};
void *ptr = &arr;
ptr = ptr + sizeof(int);
printf("%d\n", *(int *)ptr);
return 0;
}
May be other compilers generate an error.

You can't do pointer arithmetic on void * types, for exactly this reason!

Void pointers can point to any memory chunk. Hence the compiler does not know how many bytes to increment/decrement when we attempt pointer arithmetic on a void pointer. Therefore void pointers must be first typecast to a known type before they can be involved in any pointer arithmetic.
void *p = malloc(sizeof(char)*10);
p++; //compiler does how many where to pint the pointer after this increment operation
char * c = (char *)p;
c++; // compiler will increment the c by 1, since size of char is 1 byte.

You have to cast it to another type of pointer before doing pointer arithmetic.

[answer copied from a comment on a later, duplicate question]
Allowing arithmetic on void pointers is a controversial, nonstandard extension. If you're thinking in assembly language, where pointers are just addresses, arithmetic on void pointers makes sense, and adding 1 just adds 1. But if you're thinking in C terms, using C's model of pointer arithmetic, adding 1 to any pointer p actually adds sizeof(*p) to the address, and this is what you want pointer arithmetic to do, but since sizeof(void) is 0, it breaks down for void pointers.
If you're thinking in C terms you don't mind that it breaks down, and you don't mind inserting explicit casts to (char *) if that's the arithmetic you want. But if you're thinking in assembler you want it to just work, which is why the extension (though a departure from the proper definition of pointer arithmetic in C) is desirable in some circles, and provided by some compilers.

Pointer arithmetic is not allowed in the void pointer.
Reason: Pointer arithmetic is not the same as normal arithmetic, as it happens relative to the base address.
Solution: Use the type cast operator at the time of the arithmetic, this will make the base data type known for the expression doing the pointer arithmetic.
ex: point is the void pointer
*point=*point +1; //Not valid
*(int *)point= *(int *)point +1; //valid

Compiler knows by type cast. Given a void *x:
x+1 adds one byte to x, pointer goes to byte x+1
(int*)x+1 adds sizeof(int) bytes, pointer goes to byte x + sizeof(int)
(float*)x+1 addres sizeof(float) bytes,
etc.
Althought the first item is not portable and is against the Galateo of C/C++, it is nevertheless C-language-correct, meaning it will compile to something on most compilers possibly necessitating an appropriate flag (like -Wpointer-arith)

Related

arithmetic on Void Pointers in C [duplicate]

When a pointer to a particular type (say int, char, float, ..) is incremented, its value is increased by the size of that data type. If a void pointer which points to data of size x is incremented, how does it get to point x bytes ahead? How does the compiler know to add x to value of the pointer?
Final conclusion: arithmetic on a void* is illegal in both C and C++.
GCC allows it as an extension, see Arithmetic on void- and Function-Pointers (note that this section is part of the "C Extensions" chapter of the manual). Clang and ICC likely allow void* arithmetic for the purposes of compatibility with GCC. Other compilers (such as MSVC) disallow arithmetic on void*, and GCC disallows it if the -pedantic-errors flag is specified, or if the -Werror-pointer-arith flag is specified (this flag is useful if your code base must also compile with MSVC).
The C Standard Speaks
Quotes are taken from the n1256 draft.
The standard's description of the addition operation states:
6.5.6-2: For addition, either both
operands shall have arithmetic type,
or one operand shall be a pointer to
an object type and the other shall
have integer type.
So, the question here is whether void* is a pointer to an "object type", or equivalently, whether void is an "object type". The definition for "object type" is:
6.2.5.1: Types are partitioned into object types (types that fully describe objects) , function types (types that describe functions), and incomplete types (types that describe objects but lack information needed to determine their sizes).
And the standard defines void as:
6.2.5-19: The void type comprises
an empty set of values;
it is an incomplete type that cannot
be completed.
Since void is an incomplete type, it is not an object type. Therefore it is not a valid operand to an addition operation.
Therefore you cannot perform pointer arithmetic on a void pointer.
Notes
Originally, it was thought that void* arithmetic was permitted, because of these sections of the C standard:
6.2.5-27: A pointer to void shall have the same representation and alignment
requirements as a pointer to a
character type.
However,
The same representation and alignment
requirements are meant to imply
interchangeability as arguments to
functions, return values from
functions, and members of unions.
So this means that printf("%s", x) has the same meaning whether x has type char* or void*, but it does not mean that you can do arithmetic on a void*.
Pointer arithmetic is not allowed on void* pointers.
cast it to a char pointer an increment your pointer forward x bytes ahead.
The C standard does not allow void pointer arithmetic. However, GNU C is allowed by considering the size of void is 1.
C11 standard §6.2.5
Paragraph - 19
The void type comprises an empty set of values; it is an incomplete
object type that cannot be completed.
Following program is working fine in GCC compiler.
#include<stdio.h>
int main()
{
int arr[2] = {1, 2};
void *ptr = &arr;
ptr = ptr + sizeof(int);
printf("%d\n", *(int *)ptr);
return 0;
}
May be other compilers generate an error.
You can't do pointer arithmetic on void * types, for exactly this reason!
Void pointers can point to any memory chunk. Hence the compiler does not know how many bytes to increment/decrement when we attempt pointer arithmetic on a void pointer. Therefore void pointers must be first typecast to a known type before they can be involved in any pointer arithmetic.
void *p = malloc(sizeof(char)*10);
p++; //compiler does how many where to pint the pointer after this increment operation
char * c = (char *)p;
c++; // compiler will increment the c by 1, since size of char is 1 byte.
You have to cast it to another type of pointer before doing pointer arithmetic.
[answer copied from a comment on a later, duplicate question]
Allowing arithmetic on void pointers is a controversial, nonstandard extension. If you're thinking in assembly language, where pointers are just addresses, arithmetic on void pointers makes sense, and adding 1 just adds 1. But if you're thinking in C terms, using C's model of pointer arithmetic, adding 1 to any pointer p actually adds sizeof(*p) to the address, and this is what you want pointer arithmetic to do, but since sizeof(void) is 0, it breaks down for void pointers.
If you're thinking in C terms you don't mind that it breaks down, and you don't mind inserting explicit casts to (char *) if that's the arithmetic you want. But if you're thinking in assembler you want it to just work, which is why the extension (though a departure from the proper definition of pointer arithmetic in C) is desirable in some circles, and provided by some compilers.
Pointer arithmetic is not allowed in the void pointer.
Reason: Pointer arithmetic is not the same as normal arithmetic, as it happens relative to the base address.
Solution: Use the type cast operator at the time of the arithmetic, this will make the base data type known for the expression doing the pointer arithmetic.
ex: point is the void pointer
*point=*point +1; //Not valid
*(int *)point= *(int *)point +1; //valid
Compiler knows by type cast. Given a void *x:
x+1 adds one byte to x, pointer goes to byte x+1
(int*)x+1 adds sizeof(int) bytes, pointer goes to byte x + sizeof(int)
(float*)x+1 addres sizeof(float) bytes,
etc.
Althought the first item is not portable and is against the Galateo of C/C++, it is nevertheless C-language-correct, meaning it will compile to something on most compilers possibly necessitating an appropriate flag (like -Wpointer-arith)

Is conversion of a function pointer to a uintptr_t / intptr_t invalid?

Microsoft extensions to C and C++:
To perform the same cast and also maintain ANSI compatibility, you can cast the function pointer
to a uintptr_t before you cast it to a data pointer:
int ( * pfunc ) ();
int *pdata;
pdata = ( int * ) (uintptr_t) pfunc;
Rationale for C, Revision 5.10, April-2003:
Even with an explicit cast, it is invalid to convert a function pointer to an object pointer
or a pointer to void, or vice versa.
C11:
7.20.1.4 Integer types capable of holding object pointers
Does it mean that pdata = ( int * ) (uintptr_t) pfunc; in invalid?
As Steve Summit says:
The C standard is written to assume that pointers to different object types, and especially pointers to function as opposed to object types, might have different representations.
While pdata = ( int * ) pfunc; leads to UB, it seems that pdata = ( int * ) (uintptr_t) pfunc; leads to IB. This is because "Any pointer type may be converted to an integer type" and "An integer may be converted to any pointer type" and uintptr_t is integer type.
Given the definitions
int (*pfunc)();
int *pdata;
, the assignments
pdata = (int *)pfunc;
pdata = (int *)(uintptr_t)pfunc;
are, IMO, equivalent. On a platform where data pointers are of the same size as, or larger than, function pointers, both assignments will work as desired. But on a platform where data pointers are smaller than function pointers, both assignments will inevitably scrape off some of the bits of the function pointer, resulting in a data pointer which can not be converted back to the original function pointer later.
In particular, I believe that both assignments are equivalent despite the presence of the (uintptr_t) cast in the second one. I believe that cast accomplishes precisely nothing.
On a platform where data pointers are smaller than function pointers, and where type uintptr_t is of the same size as data pointers, in the assignment
pdata = (int *)(uintptr_t)pfunc;
, the cast to (uintptr_t) will scrape off some of the bits of pfunc's value.
On a platform where data pointers are smaller than function pointers, and where type uintptr_t is of the same size as function pointers, in the assignment
pdata = (int *)(uintptr_t)pfunc;
, the cast to (int *) will scrape off some of the bits of pfunc's value.
In both cases pdata will end up with only some fraction of pfunc's original value.
(Here I disregard the possibility of architectures with padding bits or the like. On some bizarre, hypothetical platform where function pointers are larger than data pointers, but the extra bits are always 0, both assignments would again work.)
(I've also disregarded the possibility that int * is a different size than void *. I'm not sure whether that would affect the answer, whether a "detour" via void * is more or less un- or necessary when attempting a conversion from int (*)() to int *.)
Casting to uintptr_t only works if this type is defined, which may not be the case on legacy systems using ancient compilers. Note however that uintptr_t must be large enough for any object pointer, especially char * or void *, but may be smaller than function pointers. Such architectures are rare today and Microsoft compilers probably no longer support them, but they were common place in the 16-bit world (MS/DOS, Windows 1, 2 and 3.x) where the medium model had 32-bit segmented code pointers and 16-bit data pointers.
Note also that the C Standard allows for int * and void * to have a different size and representation albeit no Microsoft compiler supports such exotic targets.
On current systems with modern compilers, all data pointers and code pointers have almost always the same size and representation. This is actually a requirement for POSIX compatibility, so the recommendation to use an intermediary cast to (uintptr_t) is valid and effective.
For complete portability, if the goal is to pass a function pointer via an opaque void *, you can always allocate an object of the proper function pointer type, initialize it with pfunc and pass its address:
// setting up the void *
int (*pfunc)();
void *pdata = malloc(sizeof pfunc);
memcpy(pdata, &pfunc, sizeof pfunc);
// using the void *
int (**ppfunc)() = pdata;
(*ppfunc)(); // equivalent to (**ppfunc)();
Is conversion of a function pointer to a uintptr_t / intptr_t invalid?
No. It may be valid. It may be undefined behavior.
Conversion of a function pointer to ìnt* is not defined. Nor to any object pointer. Nor to void *.
pdata = ( int * ) pfunc; is undefined behavior.
Conversion of a function pointer to an integer type is allowed, with restrictions:
Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type. C17dr 6.3.2.3 6
Also integer to a pointer type is allowed.
An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation. C17dr 6.3.2.3 6
void * to integer to void * is defined. Object pointer to/from void* is defined. Then the optional (u)intptr_t types are sufficient for round-trip success. Yet we are concerned about a function pointer. Often enough function pointers are wider than an int *.
Thus converting a function pointer to int * only makes sense through an integer type, wider the better.
VS may recommend through the optional type uintptr_t and is likely sufficient if information is lossless on other platforms. Yet uintmax_t may afford less loss of information, especially in the function pointer to integer step, so I pedantically suggest:
pdata = ( int * ) (uintmax_t) pfunc;
Regardless of the steps taken, code is likely to become implementation specific and deserves guards.
#ifdef this && that
pdata = ( int * ) (uintmax_t) pfunc;
#else
#error TBD code
#endif
Migrating the solution from the question to an answer:
Here is the answer from Microsoft:
Q: How exactly "cast the function pointer to a uintptr_t before you cast it to a data pointer" leads to maintaining "ANSI compatibility"?
A: Without the cast to uintptr_t it’s possible that the code will fail to compile with other compilers, even if they use the same pointer model. For example: https://gcc.godbolt.org/z/9EjTe1s4x - if you add the uintptr_t it compiles without warnings/errors.

Is storing a byte in a void pointer cross-platform safe?

void *vp = (void *)5;
uint8_t i = (uint8_t)vp;
Will i == 5 on all 8-bit and higher cpus? What are the risks doing this? Is there a better way to have a variable store either an 8-bit integer literal or a pointer in C99?
I have an array of function pointers to functions that take a void *. Some functions need to interpret the void * as a uint8_t.
void *vp = 5; should not compile; the C standard at least requires the compiler to issue a diagnostic message. You can request the conversion with void *vp = (void *) 5;, and you can request the reverse conversion with (uint8_t) vp. The C standard does not guarantee this will reproduce the original value. (Conversions involving pointers are specified in C 2018 6.3.2.3.) It is likely to work in most C implementations.
An alternative that would be defined by the C standard would be to use offsets into some sufficiently large object you already have. For example, if you have some array A, and you want to store some small number n in a void *, then you can do:
void *vp = (char *) A + n; // Point n bytes into the object A.
and you can recover the number with:
(char *) vp - (char *) A // Subtract base address to recover offset.
The C standard does allow for conversions between an integer and a pointer, however it doesn't explain exactly how it should happen. That is left up to each specific implementation.
Section 6.3.2.3 p5-6 of the C standard describes these conversions:
5 An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined,
might not be correctly aligned, might not point to an entity
of the referenced type, and might be a trap representation.
6 Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the
result cannot be represented in the integer type,the behavior
is undefined. The result need not be in the range of values
of any integer type.
Under gcc in particular what you're doing will work, however it's not guaranteed to work on all compilers or architectures.
What is guaranteed to work however is to take the address of a compound literal:
void *vp = &(uint8_t){5};
uint8_t i = *(uint8_t *)vp;
This creates a temporary object of type uint8_t and takes its address. This address can then be converted to a void * and back which is fully standard compliant, as per paragraph 1 of 6.3.2.3:
A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.
The lifetime of the compound literal is that of the block in which it is defined. So as long the pointer isn't used after that block ends it will work.
If however you intend to pass it to a function that starts a thread, you're better off dynamically allocating memory for the value and passing that. Otherwise, you run the risk of the function where the compound literal is defined returning while the thread function is running which could attempt to use that pointer.

Didn't understand the output of this code [duplicate]

When a pointer to a particular type (say int, char, float, ..) is incremented, its value is increased by the size of that data type. If a void pointer which points to data of size x is incremented, how does it get to point x bytes ahead? How does the compiler know to add x to value of the pointer?
Final conclusion: arithmetic on a void* is illegal in both C and C++.
GCC allows it as an extension, see Arithmetic on void- and Function-Pointers (note that this section is part of the "C Extensions" chapter of the manual). Clang and ICC likely allow void* arithmetic for the purposes of compatibility with GCC. Other compilers (such as MSVC) disallow arithmetic on void*, and GCC disallows it if the -pedantic-errors flag is specified, or if the -Werror=pointer-arith flag is specified (this flag is useful if your code base must also compile with MSVC).
The C Standard Speaks
Quotes are taken from the n1256 draft.
The standard's description of the addition operation states:
6.5.6-2: For addition, either both
operands shall have arithmetic type,
or one operand shall be a pointer to
an object type and the other shall
have integer type.
So, the question here is whether void* is a pointer to an "object type", or equivalently, whether void is an "object type". The definition for "object type" is:
6.2.5.1: Types are partitioned into object types (types that fully describe objects) , function types (types that describe functions), and incomplete types (types that describe objects but lack information needed to determine their sizes).
And the standard defines void as:
6.2.5-19: The void type comprises
an empty set of values;
it is an incomplete type that cannot
be completed.
Since void is an incomplete type, it is not an object type. Therefore it is not a valid operand to an addition operation.
Therefore you cannot perform pointer arithmetic on a void pointer.
Notes
Originally, it was thought that void* arithmetic was permitted, because of these sections of the C standard:
6.2.5-27: A pointer to void shall have the same representation and alignment
requirements as a pointer to a
character type.
However,
The same representation and alignment
requirements are meant to imply
interchangeability as arguments to
functions, return values from
functions, and members of unions.
So this means that printf("%s", x) has the same meaning whether x has type char* or void*, but it does not mean that you can do arithmetic on a void*.
Pointer arithmetic is not allowed on void* pointers.
cast it to a char pointer an increment your pointer forward x bytes ahead.
The C standard does not allow void pointer arithmetic. However, GNU C is allowed by considering the size of void is 1.
C11 standard §6.2.5
Paragraph - 19
The void type comprises an empty set of values; it is an incomplete
object type that cannot be completed.
Following program is working fine in GCC compiler.
#include<stdio.h>
int main()
{
int arr[2] = {1, 2};
void *ptr = &arr;
ptr = ptr + sizeof(int);
printf("%d\n", *(int *)ptr);
return 0;
}
May be other compilers generate an error.
You can't do pointer arithmetic on void * types, for exactly this reason!
Void pointers can point to any memory chunk. Hence the compiler does not know how many bytes to increment/decrement when we attempt pointer arithmetic on a void pointer. Therefore void pointers must be first typecast to a known type before they can be involved in any pointer arithmetic.
void *p = malloc(sizeof(char)*10);
p++; //compiler does how many where to pint the pointer after this increment operation
char * c = (char *)p;
c++; // compiler will increment the c by 1, since size of char is 1 byte.
You have to cast it to another type of pointer before doing pointer arithmetic.
[answer copied from a comment on a later, duplicate question]
Allowing arithmetic on void pointers is a controversial, nonstandard extension. If you're thinking in assembly language, where pointers are just addresses, arithmetic on void pointers makes sense, and adding 1 just adds 1. But if you're thinking in C terms, using C's model of pointer arithmetic, adding 1 to any pointer p actually adds sizeof(*p) to the address, and this is what you want pointer arithmetic to do, but since sizeof(void) is 0, it breaks down for void pointers.
If you're thinking in C terms you don't mind that it breaks down, and you don't mind inserting explicit casts to (char *) if that's the arithmetic you want. But if you're thinking in assembler you want it to just work, which is why the extension (though a departure from the proper definition of pointer arithmetic in C) is desirable in some circles, and provided by some compilers.
Pointer arithmetic is not allowed in the void pointer.
Reason: Pointer arithmetic is not the same as normal arithmetic, as it happens relative to the base address.
Solution: Use the type cast operator at the time of the arithmetic, this will make the base data type known for the expression doing the pointer arithmetic.
ex: point is the void pointer
*point=*point +1; //Not valid
*(int *)point= *(int *)point +1; //valid
Compiler knows by type cast. Given a void *x:
x+1 adds one byte to x, pointer goes to byte x+1
(int*)x+1 adds sizeof(int) bytes, pointer goes to byte x + sizeof(int)
(float*)x+1 addres sizeof(float) bytes,
etc.
Althought the first item is not portable and is against the Galateo of C/C++, it is nevertheless C-language-correct, meaning it will compile to something on most compilers possibly necessitating an appropriate flag (like -Wpointer-arith)

Is explicit type conversion necessary in A a = (A) b;

I am reading some open-source C code and encountering A a = (A) b; type conversion many times. For example,
static void hexdump(const void* pv, int len)
{
const unsigned char* p = (const unsigned char*) pv;
// some other code
}
A a = (A) b; code happens mainly when b is a pointer, void * pointer most often. I have C++ background. I think in C++, the assignment operator takes= care of the type conversion automatically? Because it already know that a is of type A.
Is the explicit type conversion necessary in C?
No, conversion from void* to char* in C (it's a common example to explain where they're different!) is implicit so casting is unnecessary (then wrong because it may hide a problem if you wrongly change char to int).
Quoting "The C Programming Language, 2nd edition" by K&R (§A.6.8):
Any pointer to an object may be converted to type void* without loss of information. If the result is converted back to the original pointer type, the original pointer is recovered. Unlike the pointer-to-pointer conversions discussed in Par.A.6.6, which generally require an explicit cast, pointers may be assigned to and from pointers of type void*, and may be compared with them.
Please note "If the result is converted back to the original pointer type" because is crucial: if instead of char* you had int* then it may be wrong because of memory alignment.
From C99 standard (§6.3.2.3) about when conversion is possible:
A pointer to void may be converted to or from a pointer to any incomplete or object type. A pointer to any incomplete or object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.
Now let's see when can be implicit (thanks to mafso for very quick search), from C11 (n1570) §6.5.4p3:
Conversions that involve pointers, other than where permitted by the constraints of 6.5.16.1, shall be specified by means of an explicit cast.
Then §6.5.16.1:
One of the following shall hold: [...] the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) one operand is a pointer to an object 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
You've got it the other way around: the cast is absolutely necessary in C++, but it is not necessary in C.
This will compile in C, but not in C++:
static void hexdump(const void* pv, int len) {
const unsigned char* p = pv;
...
}
It is not necessary in C but it helps silent compiler warnings for implicit casts in some cases.
In C++ however you need explicit casts to cast a void pointer into a pointer of a different type.
In my practice, no casting at first, though there's compiler warnings, after testing pass, casting is added to eliminate warnings.
In this case you are making a cast.
You are just saying for the compile. Hey, I'm sure that this is a type (A).
C++ style casts are checked by the compiler. C style casts aren't and can fail at runtime
It's called a cast. It means that it converts b in the (A) type.
char c = 'a'; // c is a char
int b = (int) c // you tell your compiler to interpret c as an int

Resources