83

I've been confused with what I see on most C programs that has unfamiliar function declaration for me.

void *func_name(void *param){
    ...
}

What does * imply for the function? My understanding about (*) in a variable type is that it creates a pointer to another variable thus it can be able to track what address at which the latter variable is stored in the memory. But in this case of a function, I don't know what this * asterisk implies.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Aldee
  • 4,439
  • 10
  • 48
  • 71
  • 7
    It would be very interesting question to ask the person who wrote the code why they put the asterisk next to the name of the function, rather than `void* func_name` or `void * func_name`. If they can come up with a rational argument why, I would be impressed. – Lundin Jan 18 '12 at 15:28
  • 14
    Rational argument: because we're used to writing "int *a", so it seems more consistent to do the same for functions – Guillaume Jan 18 '12 at 16:28
  • 1
    In addition to what Guillaume wrote the comming out of the function is a pointer that is to void. same as with `int *a` it is a pointing to a integer not that a is of type integer-pointer. – dhein Jul 17 '15 at 09:49
  • 1
    @Guillaume idiotic stuff. Because my teacher thought like you, I always got confused with pointers. Why the hell would we write **int *a** in the first place, here like declaration in C++ goes: **[type] [name]**. **a** is variable of type "pointer to int", why the hell would we put a asterisk on the other side of a space? It has nothing to do with name, it refers to TYPE, **a** is of "POINTER TO INT" type. I asked my teacher exact same question 10 years ago, that OP wrote, what the hell is asterisk before function name, what does it have to do with function name? – Roman Apr 18 '16 at 14:08
  • @Zaibis exactly **a is of type integer-pointer**, but this is how it's said the right way: **a is of type POINTER TO INTEGER** – Roman Apr 18 '16 at 14:13
  • @Roman id fe need to declare two pointers to int we want to write`int* a,b;`: What is the type of `b`? It's `int`, therefore we need to write `int* a, *b;` or rather `int *a, *b`. – Jabberwocky Aug 02 '21 at 09:44

4 Answers4

93

The asterisk belongs to the return type, and not to the function name, i.e.:

void* func_name(void *param) { . . . . . }

It means that the function returns a void pointer.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • 20
    thanks for the answers guys but what does a void pointer mean? – Aldee Jan 18 '12 at 13:55
  • 11
    It's just an address to a location in memory. You don't know what it points to - it's up to you to cast the pointer to a proper type that you can later use. Of course, casting it to an invalid type (for example, let's say that void* points to a float, but you cast it to a char) will produce undefined results. – Daniel Kamil Kozar Jan 18 '12 at 13:56
  • 1
    @AldeeMativo: Also, see http://stackoverflow.com/questions/692564/concept-of-void-pointer-in-c-programming – NPE Jan 18 '12 at 13:57
  • 9
    @DanielKamilKozar In C we don't cast pointers-to-void. We simply assign them. That's how it is standardized to work. (Unlike C++, which is a totally different beast.) – Jens Aug 05 '14 at 20:53
  • @Jens : true, of course. Thanks for pointing this out. Thankfully, my knowledge has improved since then. :) – Daniel Kamil Kozar Aug 06 '14 at 13:35
  • How about this one `Status (*fn)(shape_inference::InferenceContext*)` from [link](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/framework/op.h#L249) ? It uses parenthesis to group * with function name together. – skytree Aug 05 '18 at 19:26
  • A void pointer is a pointer to a data of unspecified type. It must be typecast to a specific type of pointer before you can access the data the pointer points to. You access that data by "dereferencing" (ex: int a = 1; int* ptr = &a; int x = *ptr). The last line assignes 1 to variable x from the pointer. If it was a void pointer, that would have failed. – Allison B Nov 13 '22 at 03:55
27

The * refers to the return type of the function, which is void *.

When you declare a pointer variable, it is the same thing to put the * close to the variable name or the variable type:

int *a;
int* a;

I personally consider the first choice more clear because if you want to define multiple pointers using the , separator, you will have to repeat the * each time:

int *a, *b;

Using the "close to type syntax" can be misleading in this case, because if you write:

int* a, b;

You are declaring a pointer to int (a) and an int (b).

So, you'll find that syntax in function return types too!

Vincenzo Pii
  • 18,961
  • 8
  • 39
  • 49
  • 4
    "if you want to define multiple pointers using the , operator". This is considered poor programming style since it leads to bugs when combining pointers and variables of the same type. The solution isn't to obfuscate the way you declare pointers, the solution is to _declare every variable on a line of its own_. There does not exist any case where it makes sense to declare several variables on the same row. What are you trying to achieve by doing so, save keyboard presses? Clearly, wear and tear of the keyboard is a more serious matter than readability of the code... – Lundin Jan 18 '12 at 15:35
  • 2
    I never said I do that. I said that is a reason to prefer the "close-to-variable-name" syntax, because it never creates confusion. And I said that is a possible explanation for the same syntax used in function interfaces. – Vincenzo Pii Jan 18 '12 at 16:45
  • 1
    `if you want to define multiple pointers using the , operator, you will have to repeat the * each time: int *a, *b;` In that context, the comma is a separator, not an operator. – Dan Jan 19 '12 at 03:24
  • But why for function declarations? – SOFe Jul 09 '16 at 08:56
  • @PEMapModder, that's just the return type of the function, in this case a pointer to `void`. – Vincenzo Pii Jul 10 '16 at 10:09
  • @VincenzoPii I understand that placing the deref operator closer to the var name can avoid confusion in var declaration lists, but I don't understand why this is also true for functions. You don't have one return type declaration for multiple function declarations anyway. – SOFe Jul 10 '16 at 10:38
  • @PEMapModder I'd say that would be a consistency choice based on the convention that one would follow for variables to avoid confusions there. In other words, chose where to put the `*` because of variable lists (whatever uninfluential this use case may be) and stick to that for other cases :). – Vincenzo Pii Jul 11 '16 at 11:30
  • I see. Somehow it only feels more confusing... `int *operator*(int i){...}`... Doesn't that make code less readable? – SOFe Jul 11 '16 at 14:32
  • @Lundin I agree with you, and I do not do this myself, but I think people do it for the sake of compactness, which is related to readability. Out of interest, do you have a problem with doing it for declaring non-pointers? `short a, b, c;` etc.? – RoG Apr 25 '18 at 12:18
  • @RoG Yes, that is poor style as well, because it doesn't need much to fall apart into an unreadable mess. `short a=VERBOSE_CONSTANT,b=something?this:that,c=call_some_function();`. Now sneak some `*` in there and you have a candidate for the IOCCC. – Lundin Apr 25 '18 at 12:28
  • I second @SOFe here. This post gives a good point but the example does not address the specific question thus causes confusion. – ywu Apr 13 '21 at 18:29
15

The * belongs to the return type. This function returns void *, a pointer to some memory location of unspecified type.

A pointer is a variable type by itself that has the address of some memory location as its value. The different pointer types in C represent the different types that you expect to reside at the memory location the pointer variable refers to. So a int * is expected to refer to a location that can be interpreted as a int. But a void * is a pointer type that refers to a memory location of unspecified type. You will have to cast such a void pointer to be able to access the data at the memory location it refers to.

x4u
  • 13,877
  • 6
  • 48
  • 58
5

It means that the function returns a void*.

hmjd
  • 120,187
  • 20
  • 207
  • 252