首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >init_seg和从库代码警告C4073?

init_seg和从库代码警告C4073?
EN

Stack Overflow用户
提问于 2015-08-19 01:19:46
回答 1查看 694关注 0票数 2

我们有一个C++库。它有四个对初始化顺序敏感的静态对象(其中两个是来自标准库的字符串)。

我们使用init_seg(lib)来控制库中C++静态对象的初始化顺序。正在使用它的源文件被编译并在动态链接库或静态库中使用。根据init_seg的文档

..。在需要初始化的init_seg动态链接库(DLL)或库中使用实用程序尤其重要。(强调地雷)

Visual解决方案被组织为四个项目。一个是静态库,或者是动态库,一个是静态库的测试驱动程序,另一个是动态库的测试驱动程序。

在Visual下,使用init_seg警告C4073中编译源文件,将文本初始化器放在库初始化区域。根据MSDN:

只有第三方库开发人员应该使用库初始化区域,这是由#杂注init_seg指定的。下面的示例生成C4073..。

使用init_seg的代码仅在库中使用,与测试驱动程序一起使用的是而不是。我已经验证了静态库和动态库项目设置,它们清楚地调用了库构件。

为什么我会收到C4073警告?

EN

回答 1

Stack Overflow用户

发布于 2015-08-19 01:27:57

这只是警告你,甚至连一根手指都不摇动,它更像是“你确定吗?”当您使用使用此功能的第三方库时,它也警告它的开发人员--除非他用#pragma warning关闭它。你也可以这么做。或者您可以使用段user而不是分段lib:您的字符串仍将在应用程序代码运行之前构造。段lib的真正意图是.哦,Qt或MFC或类似的框架,在运行任何应用程序代码之前都需要初始化,包括user中的早期初始化内容。

以下是更多信息:

假设您有自己的应用程序库。在运行任何代码之前,它都需要初始化一些东西,因为这个库公开的某些类打算在应用程序代码中静态分配(或允许),而这些类在它们的构造函数中执行复杂的操作,这些构造函数需要一些大型的预先计算(但不是静态的)数据。因此,对于预先计算的内容,您在类的构造函数(另一个类)中预计算它,然后静态地分配该类的一个实例,以便该实例的初始化调用它的构造函数,该构造函数预先计算所有内容,以及您用pragma init_seg(user)标记的静态实例。现在,在运行任何应用程序代码之前--包括代码中该库类的静态实例的任何构造函数--库的init_seg(user)代码都将运行,因此,在构造库类的静态实例时,它们需要的数据就在那里了。

现在,考虑一些必须尽早出现的东西,其中存在可以调用的静态实例。例如,std::cout。可以在具有静态实例的类的构造函数中调用std::cout上的方法。显然,在运行任何代码之前,都需要初始化对象std::cout。您的一些代码可能运行在标记为init_seg(user)的内容中。因此,微软将所有这些代码--即std::cout等的构造函数--放在init_seg(compiler)中。那东西会比其他任何东西都快。

那么init_seg(lib)是用来做什么的呢?那么,假设您是一个类似MFC的框架。您公开了类似于应用程序对象的东西,用户将(很有可能)创建一个静态实例。应用程序中的一些代码将在静态初始化时运行,这取决于MFC中需要初始化的其他内容。所以很明显,它需要init_seg标记,但是compiler在哪里?compiler只用于编译器和运行时,您的框架组件(MFC)可以在允许用户使用的init_seg(user)中使用.所以你得到了一个介于compileruser之间的中间层,那就是lib

现在很少需要这样的东西,因为程序使用的大多数C++库本身并不是多个库所使用的,因此不需要确保它们在所有其他“普通”库之前被初始化。MFC是这样做的,因为您可能从一个或多个供应商那里购买了第三方MFC控件或其他库,而这些供应商依赖MFC,而这些供应商可能在其构造函数中使用MFC对象,您也可能静态地使用这些库中的对象,因此需要在其他库之前对MFC进行初始化。

但在大多数情况下,您的库不会依赖于人们正在使用的其他C++库。因此,没有任何类型的依赖链需要在其他库之前初始化库。您的库可能需要在用户代码之前被初始化,是的,但是没有任何顺序需要初始化它们。所以init_seg(user)对所有的人来说都很好。

而且,微软(通常也是大多数C++专家)会告诉你:如果在应用程序静态初始化时需要初始化单独的库,那么你就错了。我是认真的。那里有个设计问题。

因此,回应一个评论:它不是编译器的错误。这是一个用户警告。相当良性的:如果你忽略它,什么都不会出错(不像忽略一个关于从长到int转换的警告)。但是,如果您使用的是init_seg(lib),您可能并不真正了解编译器特性的全部内容,所以他们希望您考虑一下。在你想过之后,如果你还想这么做,那就去把警告关掉。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32085048

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档