将解除引用的指针(即,按值)传递给期望指针的函数

时间:2014-02-16 02:15:32

标签: c pointers dereference pebble-watch pebble-sdk

我只是好奇 - 为什么C允许你在函数期望指针时传递解除引用的指针。这是一个例子:

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]);

现在编译很好,但是当我去实际使用_bla(即_bla-> what),BAM,运行时错误。

所以这让我感到困惑 - 如果它通过值传递给这个显然需要指针的函数会发生什么呢?为什么甚至编译?

我对C很新,所以请不要跳过我。 :/

*更新*

很抱歉没有提及,但这是Pebble Watch的应用程序,它使用特殊版本的gcc用于特定的臂处理器(arm-cs-tools)。

*更新2 *

我想我发现了为什么这样做。函数'cool_function'实际上是在一个单独的文件中,当我在标题中声明了该函数时,它只用void cool_function()声明 - 忘了包含Bla *_bla。但定义是void cool_function(Bla *_bla)。混淆编译器完全是我的错。

4 个答案:

答案 0 :(得分:4)

您应该收到编译器错误:

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

如果您使用gcc或clang,请尝试使用-WError和-Wall选项编译程序。

答案 1 :(得分:1)

C将不会出现编译错误,因为它缺少类型检查。在您的示例中,如果从系统的角度来看值woot[]是正确的,它甚至可能不会给出任何运行时错误

答案 2 :(得分:1)

你需要这样做:

cool_function(&woot[0]);

&在这种情况下,运算符创建引用。所以你要传递给woot [0]

的引用

请注意,这意味着cool_function()现在可以改变woot [0]的内容。如果这是不希望的,您可能想要进行某种复制操作。

例如,你可以拥有一个函数,它将Bla *复制到一个新的Bla *实例中 - 这实现了有效的传值。诀窍是你必须复制。

可选地,您可以使该函数采用const Bla * - 这样就不应该在技术上改变值。

答案 3 :(得分:1)

我已经拿走了你的代码并从中制作了一个完整的主文件:

#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]);
}

这是我尝试使用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'

所以看起来你的问题的评论都是正确的。您使用的是哪个版本的SDK?