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.
题
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?