How do you cast COM pointers in C? - c

When using COM objects it is unsafe to do a standard cast. Instead, you should use the as member function.
In C++:
//cast COMPtr1 to type COMPtrType2:
COMPtrType2 COMPtr2;
ComPtr1.as(COMPtr2);
How do I do this in C?

Related

Why do we use casting to allocate heap memory by malloc in C? [duplicate]

This question already has answers here:
Do I cast the result of malloc?
(29 answers)
Closed 2 years ago.
I got very curious to know why we use casting to allocate heap memory by malloc in C language like instructions below:
#include<stdlib.h>
int main()
{
double *var = (double*) malloc(sizeof(double));
return 0;
}
Does malloc function return an appropriate address? If so, why do we use casting?
Thanks for answering.
You don't need to cast malloc, because it returns a void*.
As wiki says: "The use of casting is required in C++ due to the strong type system, whereas this is not the case in C."
So, if you're working with C, you don't need to cast the malloc. But there are some advantages and disadvantages to do so:
Advantages:
Including the cast allows a program or function to compile as C++.
The cast allows for pre-1989 versions of malloc that originally returned a char *.
Casting can help the developer identify inconsistencies in type sizing should the destination pointer type change, particularly if the pointer is declared far from the malloc() call.
Disadvantages:
Under the ANSI C standard, the cast is redundant.
If the type of the pointer is changed, one must fix all code lines where malloc was called and cast (unless it was cast to a typedef).

C: How to access a function pointer stored in a void pointer (void *)?

Confused as to how one can access a function pointer stored in a void pointer (void *).
Let's say you have this:
void *functions[] =
{
&sqrt, // int ft_sqrt(int nb);
&power,
&logN,
&factorial;
};
// An array of void pointers, each storing a function pointer.
If I wanted to access the sqrt function, my guess would be the following:
(int (*)(int)) functions[0](x)
But my guess is wrong:
error: called object type 'void *' is not a function or function pointer
So how would one access one of these functions ?
Strictly speaking, you can't. A conversion between a function pointer and a void pointer is not possible. void* was never a generic pointer type for function pointers, only for object pointers. They are not compatible types.
In practice, any pointer will very likely have the size required by the address bus of the system, so object pointers and function pointers will very likely have the same representation. Not guaranteed by the standard though, and there are some exotic systems where this equivalence doesn't hold true. So you can cast between void* and a function pointer, but what will happen is undefined behavior. You will be relying on system-specific non-standard extensions.
Slightly better would be to use a function pointer type such as void (*)(void) as the generic pointer. You can convert to/from different function pointers, what will happen is compiler-specific (implementation-defined behavior). That is, the code will still be non-portable, but at least you don't risk a program crash from invoking undefined behavior.
It's a matter of operator precedence: The function call operator have higher precedence than the casting operator.
That means your expression (int (*)(int)) functions[0](x) is really equal to (int (*)(int)) (functions[0](x)).
You need to explicitly add parentheses in the correct places to cast the pointer: ((int (*)(int)) functions[0])(x).
A much better solution IMO would be to have an array of pointers to functions, so the array elements already is of the correct type:
typedef int (*function_ptr)(int);
function_ptr functions[] = { ... };
Then no casting is needed: functions[0](x).
Then you also would be safe from the issues mentioned in the answer by Lundin.

Casting, c programming

I got confused in interpreting this line:
a = (char*) b;
while a and b are both declared to be of type char*.
Can anyone explain it to me please?
If they are of the same type, there is no need to use casting in the expression and it is the same as
a = b;
Edit: example casting with pointers
If you are using a C++ compiler, you need casting when calling malloc function otherwise you get an error message. This function returns a void* pointer and you need to explicitly cast it to its destination type as implicit conversion from void* has not been inherited from C.

Why do we cast return value of malloc? [duplicate]

This question already has answers here:
Do I cast the result of malloc?
(29 answers)
Closed 9 years ago.
Could someone explain to me why do some programmers use (char*) in front of the malloc? I know that it returns void but why do I want it to return just char memory? I'm sorry, I'm just a newbie in programming. Thank you
No need to cast return value of malloc as its return type is void*.
Can someone explain why do some programmers use (char *) in front of the malloc?
They are doing wrong (most probably) by casting it (in good programmers opinion).
As wiki says:
malloc returns a void pointer (void *), which indicates that it is a pointer to a region of unknown data type. The use of casting is required in C++ due to the strong type system, whereas this is not the case in C1. The lack of a specific pointer type returned from malloc is type-unsafe behavior according to some programmers: malloc allocates based on byte count but not on type. This is different from the C++ new operator that returns a pointer whose type relies on the operand.
One may "cast" this pointer to a specific type:
int *ptr;
ptr = malloc(10 * sizeof (*ptr)); /* without a cast */
ptr = (int *)malloc(10 * sizeof (*ptr)); /* with a cast */
ptr = reinterpret_cast<int *>(malloc(10 * sizeof (*ptr))); /* with a cast, for C++ */
There are advantages and disadvantages to performing such a cast.
Advantages to casting:
Including the cast allows a program or function to compile as C++.
The cast allows for pre-1989 versions of malloc that originally returned a char *.
Casting can help the developer identify inconsistencies in type sizing should the destination pointer type change, particularly if the pointer is declared far from the malloc() call.
Disadvantages to casting:
Under the ANSI C standard, the cast is redundant.
Adding the cast may mask failure to include the header stdlib.h, in which the prototype for malloc is found. In the absence of a prototype for malloc, the standard requires that the C compiler assume malloc returns an int. If there is no cast, a warning is issued when this integer is assigned to the pointer; however, with the cast, this warning is not produced, hiding a bug. On certain architectures and data models (such as LP64 on 64-bit systems, where long and pointers are 64-bit and int is 32-bit), this error can actually result in undefined behavior, as the implicitly declared malloc returns a 32-bit value whereas the actually defined function returns a 64-bit value. Depending on calling conventions and memory layout, this may result in stack smashing. This issue is less likely to go unnoticed in modern compilers, as they uniformly produce warnings that an undeclared function has been used, so a warning will still appear. For example, GCC's default behavior is to show a warning that reads "incompatible implicit declaration of built-in function" regardless of whether the cast is present or not.
If the type of the pointer is changed, one must fix all code lines where malloc was called and cast (unless it was cast to a typedef).
1. Emphases are mine.
As the return type of malloc is void*, when you assign the result to a pointer, it is converted implicitly to the new type. So, there is no need for explicit casting. Actually, using an explicit cast is discouraged, as described here.
malloc returns void*, which is a generic pointer that can point to any type of data. The (char*) is an explicit type conversion, converting the pointer returned by malloc from a pointer to anything, to a pointer to char. This is unnecessary in C, since it is done implicitly, and it is actually recommended not to do this, since it can hide some errors.
If you need the code to compile as C++ too, and not just as C, you will however need the explicit conversion, since C++ doesn't perform the implicit conversion.
malloc() return a void*, as malloc() does not know how its caller will be using the memory it allocated on the heap.
So it's up to you, the caller to cast the (void*), into the appropriate type of pointer, that you want to use inside the memory.
(int*) to store integers.
(char*) to store characters etc..
Having said so, you don't have to explicitly cast the return of a malloc() call. And in some cases, doing so may result in bugs.
Kindly read up the issue here
What's wrong with casting malloc's return value?
Specifically, what's dangerous about casting the result of malloc?

How does casting a function actually work in C?

int foo(char *c) {...}
main() {
int (*thud)(void *);
thud = (int (*)(void *))(foo);
}
What actually happens during the evaluation of the assignment?
There is a difference between the cast type and foo; the cast type is a pointer and foo is a function. So, does the compiler convert what's in '(foo)' into a pointer to foo and only then make the cast? Because nothing else seems to make sense; the other option is that the function itself is converted to a pointer to a function that gets a void* and returns an int, and as far as I know a function is a label to a piece of code in memory and thus cannot become a pointer, which is a variable.
The name of a function is a pointer when used as such. It's somewhat similar to how the name of an array is a pointer to its first element.
That being said, calling a function through a pointer with a different type than the function's actual prototype (as your example does) is undefined behavior. Don't do it.
Addendum
If a converted pointer is used to call a function whose type is not compatible with the pointed-to type, the behavior is undefined.
from section 6.3.2.3 of the C standard.
In C, absolutely nothing. It is just compiler glue to prevent you from doing something stupid. In C, the caller is responsible for maintaining the stack frame, so the cast is necessary when you invoke the function (i.e. arguments and the return value are pushed onto the stack). This makes it safe(r) since the caller's stack will not likely be mutated improperly. However, the invoked function can still mess up the caller's stack in certain rare cases.
I should clarify that the assignment copies the function pointer. But in C, all function pointers are just pointers. The type and casting is all compiler glue.
Another clarification: The standard specifies (in 6.5.2.2) that the behavior is undefined if the caller uses incompatible types. For example, casting a function which returns void into one which returns an int and then calling that function, the "returned" value is meaningless. It's a good idea to cast the function into a compatible type before calling it, or you may see unexpected results.
A pointer in C is an address, i.e. a number stored in some place. A function in C is an address to some code. Those two are one of the same.
The correct term is decay. Function foo decays to a pointer to foo before the cast. The cast itself will be a no-op on all platforms I can think of.
Note, however, that the behavior of a program containing such a cast is undefined by the C standard.
This was going to be a comment to Rick C. Petty's answer - but it doesn't fit in 300 characters.
The C standard is not very restrictive - pointers to objects (and functions aren't objects) can be converted to 'pointer to void' and back without problem. POSIX requires that pointers to functions are all the same size and can be converted to pointer to void.
POSIX 2008 - General Information - The Compilation Environment
2.12.3 Pointer Types
All function pointer types shall have the same representation as the type pointer to void. Conversion of a function pointer to void * shall not alter the representation. A void * value resulting from such a conversion can be converted back to the original function pointer type, using an explicit cast, without loss of information.
Note:
The ISO C standard does not require this, but it is required for POSIX conformance.

Resources