I was just curious - why does C allow you to pass dereferenced pointers when a function is expecting a pointer. Here's an example:

typedef struct {
char message[255];
} Bla;  

// so he's the function that's expecting the pointer
void cool_function(Bla *_bla) {

}

Bla *woot = (Bla *)malloc(2 * sizeof(Bla));

woot[0] = (Bla) {
    .message = "bla bla bla"
};

// woot itself is a pointer, but it's getting dereferenced when I am adding [0]
cool_function(woot[0]);

Now that compiles fine, but when I go to actually use _bla (ie. _bla->what), BAM, runtime error.

So this confuses me -- what happens to it if it's passed by value to this function that is clearly expecting a pointer? Why does it even compile?

I'm fairly new to C, so please don't jump all over me. :/

* UPDATE *

Sorry for not mentioning earlier, but this is an app for the Pebble Watch, which is using a special version of gcc for specific arm processors (arm-cs-tools).

* UPDATE 2 *

I think I found out why it was doing that. The function 'cool_function' was actually in a separate file, and when I declared the function in the header, it was only declared with void cool_function() - forgot to include Bla *_bla. But the definition was void cool_function(Bla *_bla). It was all my fault for confusing the compiler.

有帮助吗?

解决方案

You should get the compiler error:

error: passing 'Bla' to parameter of incompatible type 'Bla *'; take the address with &
    cool_function(woot[0]);

If you use gcc or clang, try to compile your program with -WError and -Wall options.

其他提示

C will give no compile error because it lacks type checking. In your example it may even not give any runtime error as well, if the values woot[] are proper from system point of view

You need to do:

cool_function(&woot[0]);

The & operator in this case creates a reference. So you're passing a reference to woot[0]

Note that this means cool_function() can now mutate the contents of woot[0]. If this is undesired, you probably want to do some sort of copy operation.

You could have, for instance, a function that takes a Bla* that copies it into a new instance of Bla* -- this achieving effectively pass-by-value. The trick is you have to do a copy.

Optionally you can make the function take a const Bla* -- that way it shouldn't be able to mutate the values either, technically.

I have taken your code and made a full main file from it:

#include <pebble.h>

typedef struct {
  char message[255];
} Bla;

// so he's the function that's expecting the pointer
void cool_function(Bla *_bla) {

}

int main() {
  Bla *woot = (Bla *)malloc(2 * sizeof(Bla));

  woot[0] = (Bla) {
      .message = "bla bla bla"
  };

  // woot itself is a pointer, but it's getting dereferenced when I am adding [0]
  cool_function(woot[0]);
}

This is what I get when I try to compile it with Pebble SDK 2.0.0:

./src/test.c: In function 'main':
../src/test.c:20:3: error: incompatible type for argument 1 of 'cool_function'
../src/test.c:8:6: note: expected 'struct Bla *' but argument is of type 'Bla'

So it looks like comments on your question are all correct. What version of the SDK were you using?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top