【问题标题】:return double from C function, using macro expansion从 C 函数返回 double,使用宏扩展
【发布时间】:2017-11-13 17:14:33
【问题描述】:

为什么使用 double 时以下不起作用(它使用 int 起作用)

test.c

#include "myFcn.h"
#include <stdio.h>


int main () {

    printf("L1: %f \n", myGet_L1());

    mySet_L1(10.0);

    printf("L1: %f \n", myGet_L1());

    return 0;
}

myFcn.c

#include "myFcn.h"

double L1 = 0.0;

double get(double *v) {
     return *v;
}

void set(double *variable, double value) {
    *variable = value;
}

myFcn.h

 #ifndef __MYFCN_H__
 #define __MYFCN_H__

 extern double L1;
 #define myGet_L1()                  get(&L1)
 #define mySet_L1(value)             set(&L1, (value))

 #endif

我不明白为什么这在使用 int 而不是 doubles 时有效?

【问题讨论】:

  • 你需要test.c中getset的函数原型。
  • 为什么将 L1 声明为全局意大利面条变量?有什么特殊原因不能对 myFcn.c 私有?
  • 获取新的编译器!隐式 int 函数声明在 18 年前被禁止。为什么有人会使用一个在过去 18 年里没有更新过的编译器? (如果 gcc 版本低于 5.0,问题通常是配置错误。使用-std=c11 -pedantic-errors。)
  • @Lundin,它不能是私有的,因为它用于宏扩展。即,test.c:11:25:错误:使用未声明的标识符“L1”,./myFcn.h:7:42:注意:从宏“myGet_L1”扩展
  • @user3502042 是啊,你为什么在宏扩展中使用它?这完全是多余的,并且与私有封装相矛盾。 static double L1 = 0.0; ... double get(void) { return L1; }; ... void set (double value) { L1 = value; }

标签: c macros double expansion


【解决方案1】:

首先注释:启用编译器警告!这样,您可能已经自己找到了答案:

test.c 的编译单元错过了 get()set()原型,因此它们被隐式假定为

int get();
int set();

这意味着它们采用未指定数量的参数(提升int)并返回int。如果您确实将int 用于您的L1,这恰好会生成一些工作代码,但不适用于double

解决方法:在头文件中声明你的函数:

 #ifndef __MYFCN_H__
 #define __MYFCN_H__

 extern double L1;
 double get(double *);
 void set(double *, double);

 #define myGet_L1()                  get(&L1)
 #define mySet_L1(value)             set(&L1, (value))

 #endif

其他说明:

  • 另一方面,使用您提供的代码,完全没有理由让 变量本身对其他编译单元可见,所以最好删除行 p>

     extern double L1;
    
  • 以下划线开头的标识符是保留的(see this answer 用于完整的规则),因此您的 guard 宏 的命名是不明智的。只需改用MYFCN_H

【讨论】:

  • () 不是“未指定数量的int 参数”,而是“未指定数量的未指定类型的参数”。
  • @unwind: 固定的,有点,我觉得我不应该在这里讨论太多细节......
  • OP 可能正在使用仅符合 C90 的恐龙编译器。那么启用警告可能对他们没有帮助。
  • @Lundin 当然,但这是一个现实的假设吗? AFAIK,即使msvc 也应该在这里抱怨......好吧,我写了“可能”;)
  • 周围有很多恐龙编译器。不仅是 Visual Studio,还有各种或多或少奇特的嵌入式编译器。然后,SO 仍然会时不时地收到有关 Turbo C 等完全古老的编译器的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-02
  • 1970-01-01
相关资源
最近更新 更多