Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将C-struct指定的初始值设定项重写为C89(resp MSVC C编译器)_C_Visual C++_Struct_Initialization_C89 - Fatal编程技术网

如何将C-struct指定的初始值设定项重写为C89(resp MSVC C编译器)

如何将C-struct指定的初始值设定项重写为C89(resp MSVC C编译器),c,visual-c++,struct,initialization,c89,C,Visual C++,Struct,Initialization,C89,伙计们,我有个问题: 通常在C99 GCC(cygwin/MinGW/linux)中,C结构中的初始值设定项有点符号语法。 像这样: //HELP ME HOW TO REWRITE THIS (in most compact way) to MSVC static struct my_member_t my_global_three[] = { {.type = NULL, .name = "one"}, {.type = NULL, .name = "two"}, {

伙计们,我有个问题:

通常在C99 GCC(cygwin/MinGW/linux)中,C结构中的初始值设定项有点符号语法。
像这样:

//HELP ME HOW TO REWRITE THIS (in most compact way) to MSVC
static struct my_member_t my_global_three[] = {
    {.type = NULL, .name = "one"},
    {.type = NULL, .name = "two"},
    {.type = NULL, .name = "three"},
};
在头文件中定义的
my\u memeber\t
为:

struct my_member_t {
    struct complex_type * type;
    char * name;
    int default_number;
    void * opaque;
};

我正在MSVC 9.0(visualstudio 2008)中编译linux代码,在cygwin/MinGW上运行正常。
但是cl无法编译此代码(因为C99实现糟糕):
错误C2059:语法错误:'.

问题:
如何以MSVC可以编译的方式重写(许多)全局结构



向您致以最诚挚的问候,并感谢您的建议……

C99的实施情况如何?我不认为VC2008中的C编译器甚至试图实现C99。它可能借用了一些特性,但实际上是一个C89/90编译器

只需删除字段名标签

static struct my_member_t my_global_three[] = {
    { NULL, "one"},
    { NULL, "two"},
    { NULL, "three"},
};
在这种情况下很容易,因为初始值设定项在原始代码中的顺序与结构中字段的顺序相同。如果顺序不同,您必须在无标记C89/90版本中重新排列它们


如果它确实是您的
my_member\t
,那么您应该将字符串指针声明为
const char*
,或者停止使用字符串文本初始化这些成员。

谢谢您的信息,Nico

/*
 * Macro for C99 designated initializer -> C89/90 non-designated initializer
 *
 * Tested.  Works with MSVC if you undefine HAVE_DESIGNATED_INITIALIZERS.  Cscope also
 * groks this.
 *
 * ("SFINIT" == struct field init, but really, it can be used for array initializers too.)
 */
#ifdef HAVE_DESIGNATED_INITIALIZERS
#define SFINIT(f, v) f = v
#else
#define SFINIT(f, v) v
#endif

struct t {
    char f1;
    int f2;
    double f3;
};

struct t t = {
    SFINIT(.f1, 'a'),
    SFINIT(.f2, 42),
    SFINIT(.f3, 8.13)
};
但是,我发现,对于内部带有数组的结构来说,这是行不通的。我建议对C99和MSVC(在MSVC++2010 Express中验证)进行此修改:


通过这种方式,您可以为MSVC和其他编译器使用一个文件。

就是这样:-)假设未列出的字段必须显式初始化为0/NULL(因此arity匹配)。未列出的尾部字段设置为0。与C99不同,您不能跳过其他字段,因为它们必须按顺序给定。@DinGODzilla:Arity在C89/90中不需要匹配,只要您每次要跳到数组的下一个成员时都使用一对嵌套的
{}
。这意味着您只需初始化结构的前导元素,而尾随元素将自动设置为零。在这种特殊情况下,在C99中用
NULL
初始化
type
字段是不必要的,只需
.name=“something”
就足够了(
type
将自动设置为NULL),但在C89/90中,您必须明确指定
NULL
字段,才能进入下一个字段
name
@DinGODzilla:。。。。。换句话说,它看起来像是C99风格的初始化器是由C89/90风格的初始化器直接翻译而来的,它需要一个显式的<代码> null <代码>第一个字段:)……它实际上是一个C89/90编译器。“不,MSVC真的是C++编译器。他们真的不再谈论C了。请注意,VS 2013中添加了指定初始值设定项功能:我看不出这是如何在C89中实现指定初始值设定项功能的?如果我更改了值的顺序,或者省略了一些值,这就是此功能的全部要点,该怎么办?:-1:这根本不是一个可移植的解决方案。这里基本上没有定义编译器之间的初始化行为。在
HAVE_designed_INITIALIZERS==0
的情况下,这看起来更像是一种复杂的参数注释方式。与Nico的答案相同,这是不可移植的,因为初始化最终仍取决于传递值的顺序。在最坏的情况下,此代码使用不同的编译器编译,但结果不同。。。
#ifdef HAVE_DESIGNATED_INITIALIZERS
#define SFINIT(f, ...) f = __VA_ARGS__
#else
#define SFINIT(f, ...) __VA_ARGS__
#endif

typedef struct {
  int val;
  int vecB[4];
  int vecA[4];
} MyStruct_ts;

static const MyStruct_ts SampleStruct =
{
    SFINIT(.val     , 8),
    SFINIT(.vecB    , { 1, -2,  4,  -2}),
    SFINIT(.vecA    , { 1, -3,  5,  -3}),
};