Struct 为什么';MSVC是否初始化此常量结构?

Struct 为什么';MSVC是否初始化此常量结构?,struct,initialization,visual-studio-2015,Struct,Initialization,Visual Studio 2015,我有一些用C编写的代码,在使用VisualStudio2015社区时,有一个部分拒绝合作(clang没有问题)。我有一个简单的结构: /** Options for enumerating over all documents. */ typedef struct { unsigned skip; /**< The number of initial results to skip. */ C4EnumeratorFlags flags; /

我有一些用C编写的代码,在使用VisualStudio2015社区时,有一个部分拒绝合作(clang没有问题)。我有一个简单的结构:

/** Options for enumerating over all documents. */
typedef struct {
    unsigned          skip;     /**< The number of initial results to skip. */
    C4EnumeratorFlags flags;    /**< Option flags */
} C4EnumeratorOptions;

enum {
    kC4Descending           = 0x01, /**< If true, iteration goes by descending document IDs. */
    kC4InclusiveStart       = 0x02, /**< If false, iteration starts just _after_ startDocID. */
    kC4InclusiveEnd         = 0x04, /**< If false, iteration stops just _before_ endDocID. */
    kC4IncludeDeleted       = 0x08, /**< If true, include deleted documents. */
    kC4IncludeNonConflicted = 0x10, /**< If false, include _only_ documents in conflict. */
    kC4IncludeBodies        = 0x20  /**< If false, document bodies will not be preloaded, just
                               metadata (docID, revID, sequence, flags.) This is faster if you
                               don't need to access the revision tree or revision bodies. You
                               can still access all the data of the document, but it will
                               trigger loading the document body from the database. */
};
typedef uint16_t C4EnumeratorFlags;
但是,在调试时,我注意到当我尝试使用默认值时,初始化没有做任何事情:

// options winds up with a "skip" value of something like 117939945
// and a flags value of 59648
C4EnumeratorOptions options = kC4DefaultEnumeratorOptions;
定义部分在DLL中,第二个使用部分在exe中。同样,这只发生在Windows上。此外,“options”中的值是垃圾,但由于某些原因,它甚至不是存储在
kC4DefaultEnumeratorOptions
中的垃圾。我知道MSVC因强行起下钻C而臭名昭著,但这种初始化太旧了,即使是MSVC也应该做对,不是吗?所以这一定是我正在做的事情,但我不知道是什么

编辑通过导出定义文件导出符号。我使用dumpbin进行了检查,并在导出的符号列表中找到了该符号

41 46 00A6EA8 KC4默认枚举数选项=KC4默认枚举数选项


还有一个信息,调用代码是C++,DLL代码是C,我怀疑它可能在这个疯狂中扮演了一个角色。

< P> @ @ M.M的评论帮助我走上正确的方向。他问这个符号是否出口。从技术上讲,是的,它是导出的,因为它在导出列表中,但显然我还需要导出定义。因此,我不需要在.def文件中包含全局符号,而是需要在两个位置手动用
\uuudeclspec(dllexport)
\uuudeclspec(dllimport)
标记它,因此最后它看起来是这样的:

#ifdef _MSC_VER
#ifdef CBFOREST_EXPORTS
#define CBFOREST_API __declspec(dllexport)
#else
#define CBFOREST_API __declspec(dllimport)
#endif
#endif

// ...

// Header
CBFOREST_API extern const C4EnumeratorOptions kC4DefaultEnumeratorOptions;

// Implementation
CBFOREST_API const C4EnumeratorOptions kC4DefaultEnumeratorOptions = {
    0, // skip
    kC4InclusiveStart | kC4InclusiveEnd | kC4IncludeNonConflicted | kC4IncludeBodies
};

你怎么知道它“什么也没做”?而且看起来你没有输出符号@嗯,也许它在做些什么,但对我来说,这个值看起来没有初始化,因为它是完全随机的。我将检查以确保符号在导出列表中,尽管(.def文件)似乎不是特定于C的,但仅限于Windows。您应该更新问题的标记。@Olaf既然您提到了它,我就忘了提到这段代码在其他任何地方都可以正常工作。我去掉了“c”标签以避免混淆。
#ifdef _MSC_VER
#ifdef CBFOREST_EXPORTS
#define CBFOREST_API __declspec(dllexport)
#else
#define CBFOREST_API __declspec(dllimport)
#endif
#endif

// ...

// Header
CBFOREST_API extern const C4EnumeratorOptions kC4DefaultEnumeratorOptions;

// Implementation
CBFOREST_API const C4EnumeratorOptions kC4DefaultEnumeratorOptions = {
    0, // skip
    kC4InclusiveStart | kC4InclusiveEnd | kC4IncludeNonConflicted | kC4IncludeBodies
};