对于这个结构和函数:
typedef struct data_s
{
int i1;
int i2;
} data_t;
void print_data_passed_by_ptr(const data_t *data)
{
printf(" i1 = %i\n"
" i2 = %i\n\n",
data->i1,
data->i2);
}
这在 C 中工作得很好:我正在就地创建一个
data_t
结构体,并将其地址作为 R 值(意味着它没有分配给变量)传递给 print_data_passed_by_ptr()
函数:
// Print R-value struct passed by ptr
print_data_passed_by_ptr(&(data_t){
.i1 = 7,
.i2 = 8,
});
我的 C 构建命令是:
gcc -Wall -Wextra -Werror -O3 -std=c17 \
struct_pass_R_values_by_cpp_reference_and_ptr.c -o bin/a && bin/a
但是,在 C++ 中它失败了
error: taking address of temporary [-fpermissive]
我的 C++ 构建命令是:
g++ -Wall -Wextra -Werror -O3 -std=c++17 \
struct_pass_R_values_by_cpp_reference_and_ptr.c -o bin/a && bin/a
所以,我将
-fpermissive
添加到我的 C++ 构建命令中:
g++ -Wall -Wextra -Werror -O3 -std=c++17 -fpermissive \
struct_pass_R_values_by_cpp_reference_and_ptr.c -o bin/a && bin/a
现在 C++ 构建失败了:
error: taking address of temporary [-Werror=permissive]
我尝试用
-Werror=permissive
关闭 -Wno-error=permissive
(请参阅此处了解 GCC 文档:https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html,然后在页面中搜索 -Wno-error=
) ),但这不是一个有效的选项。我尝试的新构建命令:
g++ -Wall -Wextra -Werror -O3 -std=c++17 -fpermissive -Wno-error=permissive \
struct_pass_R_values_by_cpp_reference_and_ptr.c -o bin/a && bin/a
...失败:
cc1plus: error: -Werror=permissive: no option -Wpermissive
那么,我该如何解决这个问题以强制此 C 代码在 C++ 中构建? 要么抑制警告/错误,要么对代码进行一些修改除了下面显示的之外都是可接受的答案。我希望代码最终也能编译为 C,而不仅仅是 C++。
我知道我可以在C++中使用“const引用”而不是ptr,就像这样,这很好,它可能会回答别人的问题,但这不是我的问题:
void print_data_passed_by_cpp_reference(const data_t& data)
{
printf(" i1 = %i\n"
" i2 = %i\n\n",
data.i1,
data.i2);
}
// Print R-value struct passed by C++ reference
print_data_passed_by_cpp_reference({
.i1 = 9,
.i2 = 10,
});
我也知道我可以删除
-Werror
并保留 -fpermissive
来构建它,并带有警告,如下所示:
eRCaGuy_hello_world/cpp$ g++ -Wall -Wextra -O3 -std=c++17 -fpermissive \
struct_pass_R_values_by_cpp_reference_and_ptr.c -o bin/a && bin/a
struct_pass_R_values_by_cpp_reference_and_ptr.c: In function ‘int main()’:
struct_pass_R_values_by_cpp_reference_and_ptr.c:87:5: warning: taking address of temporary [-fpermissive]
});
^
Hello world.
i1 = 7
i2 = 8
i1 = 9
i2 = 10
...但我真的很想保持
-Werror
开启并让该警告消失。
(强调添加到我原来的报价中)
那么,我该如何解决这个问题以强制此 C 代码在 C++ 中构建?要么抑制警告/错误,或者对代码进行一些修改,而不是下面所示的,都是可接受的答案。我希望代码最终也编译为 C,而不仅仅是 C++。
这有效!这是一种方法。如果有办法通过命令行选项禁用 gcc 中的警告/错误,我仍然想知道这些。
我认为这非常聪明。它使用 print_data()
函数和 DATA_T
宏的两个单独定义(具体取决于语言),通过 C 的
const ptr和 C++ 的
const Reference传递 R 值。
#ifndef __cplusplus
// For C
void print_data(const data_t *data)
{
printf(" i1 = %i\n"
" i2 = %i\n\n",
data->i1,
data->i2);
}
#else
// For C++
void print_data(const data_t& data)
{
printf(" i1 = %i\n"
" i2 = %i\n\n",
data.i1,
data.i2);
}
#endif
#ifndef __cplusplus
// For C
#define DATA_T &(data_t)
#else
// For C++
#define DATA_T // leave empty
#endif
用途:
// Print R-value struct passed by C++ reference, OR by C ptr, depending on
// whether this code is compiled as C or C++
print_data(DATA_T{
.i1 = 9,
.i2 = 10,
});
构建命令:
# For C
gcc -Wall -Wextra -Werror -O3 -std=c17 \
struct_pass_R_values_by_cpp_reference_and_ptr.c -o bin/a && bin/a
# For C++
g++ -Wall -Wextra -Werror -O3 -std=c++17 \
struct_pass_R_values_by_cpp_reference_and_ptr.c -o bin/a && bin/a