I'm new to C language and pointers in general. So my understanding of these two things is basic.
I've been trying to create a structure that hold pointers to functions, nothing fancy. While doing so; I noticed that this statement:
int *func()
doesn't work. while this one actually works:
int (*func)()
What's the difference between them? Is it because the first statement is only a pointer to integer. while the other pointer, somehow, points to a function? How so?
int *func(void)
Defines a function named func that has no parameters and returns a pointer to an integer
int(*func)(void)
Defines a pointer to a function that has no parameters and returns an integer
The reason for this difference is operator precedence. Parerenteses have a higher precendence than *. Therefore in the first expression int *func() the function-parenthesis have the highest precedence and are considered first, so associate with the symbol func so the compiler knows that func is a symbol for a function. Therefore the rest is the return.
In the second instance int(*func)() there is an extra set of parenthesis. Inside the first parenthesis we see *func. As the parenthesis is the highest precendence (left-to-right) the compiler must interpret the contents of this set... *func is a pointer. OK a pointer to what? Look right and we see () so it is a pointer to a function. Then look left to see the return type.
Hope this makes sense :) Also try How to interpret complex C/C++ declarations on CodeProject.com. It talks about something called the "Right-left rule", which is "...a simple rule that allows you to interpret any declaration...". It's a little more than half way down the page...
Also try cdecl: C gibberish ↔ English. It's quite a nice implementation of the cdecl utility.
Related
This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
What makes more sense - char* string or char *string?
Pointer declarations in C++: placement of the asterisk
I've seen mixed versions of this in a lot of code. (This applies to C and C++, by the way.) People seem to declare pointers in one of two ways, and I have no idea which one is correct, of if it even matters.
The first way it to put the asterisk adjacent the type name, like so:
someType* somePtr;
The second way is to put the asterisk adjacent the name of the variable, like so:
someType *somePtr;
This has been driving me nuts for some time now. Is there any standard way of declaring pointers? Does it even matter how pointers are declared? I've used both declarations before, and I know that the compiler doesn't care which way it is. However, the fact that I've seen pointers declared in two different ways leads me to believe that there's a reason behind it. I'm curious if either method is more readable or logical in some way that I'm missing.
It's a matter of preference, and somewhat of a holy war, just like brace style.
The "C++" style
someType* somePtr;
is emphasizing the type of the pointer variable. It is saying, essentially, "the type of somePtr is pointer-to-someType".
The "C" style
someType *somePtr;
is emphasizing the type of the pointed-to data. It is saying, essentially, "the type of data pointed to by somePtr is someType".
They both mean the same thing, but it depends on if a given programmer's mental model when creating a pointer is "focused", so to speak, on the pointed-to data or the pointer variable.
Putting it in the middle (as someType * somePtr) is trying to avoid committing to either one.
It doesn't matter. Someone will now come along and close the question as a dupe, and someone else will show how the int* a way breaks if you declare multiple variables in the same declarations while int *a better reflects the syntactical structure of the code, and another one will show that Stroustrup prefers the int* a way and keeps the type together on the left side.
Many opinions, but no "right" way here.
It doesn't matter, it is personal preference.
Some people like to keep the type together:
int* p;
Other people say that it should go next to the variable because of the following:
int *p, x;//declare 1 int pointer and 1 int
int *p, *x;//declare 2 int pointers.
Over time you will just overlook this and accept both variations.
The difference arose because C++ added a stronger type system on top of C.
C style
A C programmer usually thinks in terms of "values," so
int *pValue;
reads "the dereference of pValue is an int".
C++ style
Whereas a C++ programmer thinks in "types" so
int* pValue;
reads "the type of pValue is pointer to int".
The compiler sees no difference at all of course. However you will find that it is the C programmers who insist on "value semantics" when programming in C++.
I think putting the asterisk adjacent to the name of the variable is clearer.
You might mistakenly declare someType* one, two; thinking that they are both pointers but only the variable one is a pointer; two is just a someType. Declaring as someType *one, *two avoids this problem.
Every single way I've seen ever is
TheType *myPointer
because you are declaring a POINTER of type TheType. Similar declaring
TheType myVar
would be declaring an instance variable of type TheType.
Also you can then clearly do this and have it easily readable
TheType myVar, *myPointer;
Specifically, my question is, given this macro:
#define FAKE_VAL(type) ((type)0)
...is there any value of type (including structures, function pointers, etc.) where FAKE_VAL(type) will cause a compile-time error?
I'm asking because I have a macro that take a function pointer as an argument, and needs to find the size of its return value. I know the types and number of arguments the function pointer takes, so I'm planning to write something like:
sizeof(fptr(FAKE_VAL(arg_type_1), FAKE_VAL(arg_type_2)))
arg_type_1 and 2 could be literally anything.
Of course there is.
struct fred (i.e. not a pointer) - how do you convert 0 (scalar type) to a struct (non scalar type)?
Any literal value FAKE_VAL("hi") gives (("hi")0) - what does that mean?
You can't cast an int to an array type, so
FAKE_VAL(int[5]);
will fail. Try it!
To give it a more systematic answer. In C cast are only allowed for arithmetic and pointer types. So anything that is a struct, union or array type would lead to a compile time error.
typecast is used to inform the compiler that the programmer has already considered the side effects of using the variable in a different way than it was declared as. This causes the compiler to switch off its checks. So with typecasts you wont get warnings/errors.
Yeah. it does type conversion of any type to the typecasted one. My bad.
But this can cause segmentation faults/errors when the program is actually run.
I am trying to implement an interpreter. I'd love to go with GCC first class labels to make it threaded code, but I should hold on to a standard this time, so naturally I am left with function table. So, I'm doing this:
unsigned short int FUN_TABLE[MAX_FUN] (void*);
And I want to fill it with functions, each getting pointer to its operands, doing its part, returning length of the whole instruction in memory to a dispatcher.
The thing is, I can't even compile it due to the following error: declaration of FUN_TABLE as array of functions. Considering it is exactly what I am trying to achieve, why is this an error, why should I pay it attention, and if I shouldn't, how to suppress it in elegant and standardized manner?
You can define an array of function pointers like this (pseudocode):
int (*funcArr2[10])(param, param, ...) = {NULL};
However, you should be aware that this means that all these functions have the same set of arguments. You can not declare an array with function pointers to totall different functions with regard to their signature.
GCC is telling you: "there is no such thing as an array of functions".
Considering it is exactly what I am trying to achieve, why is this an error, why should I pay it attention
Because you are trying to achieve something that does not exist in the C language. But instead, you can achieve the desired functionality through an array of function pointers.
The syntax of declaring a function pointer is
return_type (*func_ptr_name)(parameters)
and the syntax for declaring an array of function pointers is
return_type (*func_ptr_name[n])(parameters)
Since that syntax is quite obscure, you will not want to use it. The solution is to use typedefs:
typedef unsigned short (*func_table_t)(void*);
// declare an array of function pointers, using readable syntax:
func_table_t func_table [MAX_FUNC] =
{
&some_function,
&some_other_function,
...
};
Arrays of functions aren't legal. Your easiest work around would be an array of pointers to functions -- but this implies that each function being pointed to from the array has the same signature.
We are all familiar with working of sizeof operator in C language. I am trying to make a similar working function that will absorb any kind of datatype and return me its size.
Can somebody tell me how to make such a similar function in "C".
int myOwnSizeOf(/*what would be parameter type?*/)
{
//and what about the definition?
}
Thanks
You can't do that with a function. That's why sizeof is an operator built into the language, not a library function. It's magic.
You could do
#define myOwnSizeOf(x) (sizeof(x))
but I don't really see the point.
Since a function is evaluated at runtime, it can never consume a datatype but only objects. That's why sizeof is a built in operator.
You might get it to work for this limited case in C++ with a template function. But in C your only possibilities to consume an object of any datatype are either void pointers or macros. But the former won't work, of course, as it looses any type information and the latter was already suggested by aschepler and as he noted, it won't buy you anything (and it isn't a function, anyway).
A function can't do it, but a macro can, if you don't mind throwing in a little technical UB that can't/won't really matter:
#define mysizeof(T) (size_t)((char *)((T*)0+1)-(char *)0)
If you replaced 0 with the address of a static-storage-duration object larger than any other object you'd ever try to take the size of, the UB would go away.
Edit: Note that this is for types T; a version for variables is much easier:
#define mysizeof(v) (size_t)((char *)(&v+1)-(char *)&v)
For the C code below, compare the defintions of the int pointers a and b;
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *a=malloc(sizeof(int));
int *b=(int *)malloc(sizeof(int));
return(0);
}
Is it better in any way to typecast the pointer of type void, returned by the malloc function?
Or is it auto-typecasted while assigning to the int pointer on the left hand side?
Under which circumstances, if any, can it prove to be necessary rather than just obligatory?
Please clarify whether implicit type casting, where type of right hand side is converted to type of the left hand side, applies here.
The cast is not needed for the C language, but for C++ compatibility you may want to cast. This is one of the spots where C is not a subset of C++.
The following will compile in C but not C++:
int *a=malloc(sizeof(int));
The following will compile in both C and C++:
int *b=(int *)malloc(sizeof(int));
No, Yes, Never
Some people cast the pointer, I don't.
Yes, the type conversion happens "automatically"
It is never necessary in C.
In a strange way, casting the result compromises C++ portability. A module referenced from C++ will most likely be compiled as C, in which case it won't matter. But if the code is somehow copy-and-pasted into C++, I think you want each such line flagged, as a line of code calling malloc() in C++ is a suspicious LoC.
In part this is a holdover from early K&R C that had no such type as void, so malloc() returned a char *. Now, you needed to do the cast. Consequently the design pattern of casting malloc() developed and influenced all the people who wrote the next set of code, and people are stilling reading those code bodies today and carrying the pattern forward. But C89 had void and so it's time to streamline the code.
Depending on exactly how it is done, the cast may violate DRY (aka DIE.) As Chris Lutz points out, it unnecessarily reduces the level of abstraction. Since that isn't exactly sky-high in a C program to start with, I would prefer not to lose the level we do have.
To put it simply:
If you have included stdlib.h, as you should have, then the cast does absolutely nothing, and should be removed. After all, you've specified the type already.
If you have not, then the cast will cover up the error, which is bad.
Never use that cast in C code.
In C++, the cast is necessary, as C++ doesn't permit implicit conversion between void * and other pointer types. On the other hand, in C++ there are better things to use than malloc(), such as new, or container classes.
Writing code that will compile in either is pointless. You should always know what language you're writing in, and writing in the subset forces you to use a construct that's inferior in either language. The C++ compilers I'm familiar with will compile C code as well, and there are explicit provisions in C++ to link easily with C code. If you do compile it as C++, the error message (without the cast) will point out your mistake.
All the cast will do is cover up mistakes that can bite you elsewhere. It won't do anything useful. Don't do it.
In C the cast is unnecessary. malloc returns a void*, and the C standard states:
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.
Further, K&R2 says:
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.
A point may be made about C++ compatibility, as in C++ the cast is obligatory. However, IMHO this is hardly relevant, as idiomatic C++ calls for using new instead of malloc anyway.
Casting the return value of malloc() is a C++ idiom and has no place in C code. It's only necessary when you want to compile the code as C++, which you shouldn't do as C and C++ are distinct languages with diffrerent semantics.
It only makes sense if you want to make a C library which defines inline functions in header files to be usable from C++. With the advent of link-time optimizations, this hopefully won't be necessary any longer as functions can be inlined even when defined in diffrerent source files.
As to people claiming explicit casting adds to readability, consider the given example
int *b=(int *)malloc(sizeof(int));
How exactly repeating the type THREE TIMES is more readable than
int *b = malloc(sizeof *b);
is beyond me.
C++0x even added type inference to get rid of similar repetitions, so I don't really think this is controversial.
If we're talking C, best practice is to not cast the result of malloc(). If we're talking C++, best practice is to use new instead of malloc()1.
The reason I recommend against casting the result is to avoid problems if you forget to #include stdlib.h, or otherwise don't have a prototype for malloc() in scope. Up until C99, if you had a function call with no prior declaration, the compiler would implicitly type the function call to return int. Without the cast, this would result in an incompatible assignment warning. With the cast, the warning is supressed, and runtime errors could possibly result since the value returned from malloc() would be converted from a pointer to an int and back to a pointer again, which is not guaranteed to be meaningful.
If you're porting from C to C++, you might as well convert from malloc() to new up front.
Is it better in any way to typecast the pointer of type void, returned by the malloc function?
Yes. It is clearer in meaning. It's the same reason I'd write
a = b + (c * d);
Now, I know the "()"s are not needed here, due to the rules of precedence of arithmetic operators, but they help me (and others) clearly see my intent.
$.02, etc. :)
-k