【问题标题】:Check is member in struct with C检查是 C 结构中的成员
【发布时间】:2021-03-08 01:01:40
【问题描述】:

我想访问结构中的成员,但检查该成员是否存在

#include <stdio.h>

int main()
{
    struct MyStruct { int a;};
    struct MyStruct temp ;
    temp.a=3;

    return 0;
}

有没有办法检查成员 a 是否在 struct m 中,如果不能使用 #ifdef 访问 b? 类似#ifdef MyStruct.a temp.a=3; #else temp.b=3; #endif

【问题讨论】:

  • 如果该成员不存在,编译器将拒绝您的代码。不,没有一种自动方法来检测结构中是否存在用于条件编译的成员。您可以手动设置代码,例如 #define MEMBER_A_EXISTS 1#define MEMBER_A_EXISTS 0,具体取决于成员 a 是否存在,然后测试该宏。这听起来像是XY Problem——你真正的问题是什么?
  • @JonathanLeffler 对,所以我想在编译前检查一下
  • 不,那不可能。
  • 如果a 不存在,b 会成为struct MyStruct 的第一个成员吗?在这种情况下,有一个解决方案:*(int *)&amp;temp = 3;struct 的第一个成员和struct 本身可以通过强制转换互换)
  • @DavidRanieri 你是对的,我的错。我看了一眼这个问题,以为它在问别的问题(即你能检查指针是否是特定结构的成员)

标签: c struct ifdefine


【解决方案1】:

这在 C 中是不可能的。

如果你真的想要检测结构的成员,通常的方法是首先编译一个使用该结构的示例程序,看看编译是否成功,并根据结果定义与否用于编译项目其余部分的编译器的预处理器宏。创建了各种build systems 来简化此类任务。 cmake 的简短示例可能如下所示:

cat >mystruct.h <<EOF
struct MyStruct { 
    int a; // a? maybe not? no one knows.
};
EOF

cat >CMakeLists.txt <<EOF
cmake_minimum_required(VERSION 3.11)
project(test_include C)
# will try to compile a testing file
try_compile(mystruct_has_a "${CMAKE_BINARY_DIR}/temp" ${CMAKE_SOURCE_DIR}/test_mystruct_has_a.c)
add_executable(main main.c)
if(mystruct_has_a)
    target_compile_definitions(main PUBLIC MYSTRUCT_HAS_A)
endif()
EOF

cat >test_mystruct_has_a.c <<EOF
#include "mystruct.h"
int main() {
    struct MyStruct temp;
    temp.a = 3; // test - can we compile this?
}
EOF

cat >main.c <<EOF
#include <stdio.h>
#include "mystruct.h"
int main() {
    struct MyStruct temp ;
#if MYSTRUCT_HAS_A
    // it's ok to use `temp.a` here.
    temp.a = 3;
    printf("%d\n", temp.a);
#endif
}
EOF

可以从命令行编译:

cmake -S. -B_build && cmake --build _build --verbose

cmake 将尝试编译文件test_mystruct_has_a.c。如果编译成功,那么宏MYSTRUCT_HAS_A 将作为宏添加到编译器参数中。如果没有,则不会添加宏。然后main.c 将根据之前的结果使用或不使用该宏进行编译。这种方法通常用于许多不同的项目,主要是通过检测操作系统特定的东西来提供可移植性,例如sigactionsiginfo_tsched_param 的成员。

【讨论】:

    猜你喜欢
    • 2017-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-11
    • 2016-07-09
    相关资源
    最近更新 更多