【问题标题】:Pointer to function in union指向联合函数的指针
【发布时间】:2018-03-26 07:38:07
【问题描述】:

Visual Studio 在这段代码中给了我错误

typedef union
{
  double value;
  double (*UnFunc)(double);
  double (*BiFunc)(double, double);
  double (*VarAssi)(vars_t *, elem_t, elem_t, error_t *);
  void (*FuncAssi)(custom_funcs_t *, elem_t, expr_t, error_t *);
  char delimiter;
} body_t;

typedef struct
{
  const char *name;
  int priority;
  body_t body;
} elem_info_t;

static const elem_info_t s_STD_UN_FUNC[] = {
  {"sqrt",   2, sqrt},
  {"sin",    2, sin},
  {"cos",    2, cos},
  {"tg",     2, tan},

VS 说(下划线功能分配)

错误 C2440: '正在初始化': 无法从 'double (__cdecl *)(double)' 到 'double'

但是联合类型中已经存在所有类型的指针。显式类型转换会导致另一个错误。在这种情况下我应该怎么做?谢谢。

【问题讨论】:

  • 请显示 sqrt、sin 等的定义
  • 如果在union 中将double (*UnFunc)(double); 放在double value; 之前会发生什么?顺便说一句,我希望你有充分的理由使用union。它们可能有问题(您的代码就是一个例子)。
  • 那个地方的错误会消失,但在其他所有由其他类型的函数定义的地方,错误会一直存在。
  • sqtr 等来自 math.h
  • 发布的代码缺少类型的定义:elem_t、error_t、expr_t、custom_funcs_t,并且'body_t`的typedef失败。

标签: c visual-studio


【解决方案1】:

初始化联合时,如果不指定哪个成员,默认会初始化第一个成员。这就是错误的来源。

您需要使用指定的初始化器来指定要设置的成员:

static const elem_info_t s_STD_UN_FUNC[] = {
  {"sqrt",   2, { .UnFunc = sqrt}},
  {"sin",    2, { .UnFunc = sin}},
  {"cos",    2, { .UnFunc = cos}},
  {"tg",     2, { .UnFunc = tan}},
  ...

【讨论】:

  • @EveHo 很高兴我能帮上忙。如果您觉得有用,请随时 accept this answer
  • 这拯救了我的一天。没有比这更好的答案了:)
【解决方案2】:

发布的代码包含几个关键的缺失元素。

以下显示了一种可接受的代码编写方式

#include <math.h>

// set these following 5 typedefs to your actual types
typedef int error_t;
typedef int vars_t;
typedef int elem_t;
typedef int expr_t;
typedef int custom_funcs_t;

typedef union uFuncTypes
{
    double value;
    double (*UnFunc)(double);
    double (*BiFunc)(double, double);
    double (*VarAssi)(vars_t *, elem_t, elem_t, error_t *);
    void   (*FuncAssi)(custom_funcs_t *, elem_t, expr_t, error_t *);
    char   delimiter;
} body_t;

typedef struct funcStruct
{
  const char *name;
  int priority;
  body_t body;
} elem_info_t;

static const elem_info_t s_STD_UN_FUNC[] = {
  { "sqrt",   2, .body.UnFunc = sqrt },
  { "sin",    2, .body.UnFunc = sin  },
  { "cos",    2, .body.UnFunc = cos  },
  { "tg",     2, .body.UnFunc = tan  }
};

注意:对于大多数调试器,为了正确显示结构内和联合内的字段,需要在定义中包含适当的标记名称

最新的 C 标准强烈建议不要在类型名称的末尾使用 _t,因为 C 喜欢为自己保留该结尾。

【讨论】:

  • 谢谢。我会注意你的言论。我们有 _t 的 c 教育课程风格。我们用 c89 编写 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
相关资源
最近更新 更多