gpt4 book ai didi

c++ - init_seg和库代码中的警告C4073?

转载 作者:可可西里 更新时间:2023-11-01 10:35:01 25 4
gpt4 key购买 nike

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

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

... It is particularly important to use the init_seg pragma in dynamic-link libraries (DLLs) or libraries requiring initialization. (emphasis mine)



Visual Studio解决方案分为四个项目。一种是静态库,或者是动态库,一种是静态库的测试驱动程序,一种是动态库的测试驱动程序。

在Visual Studio下,使用 init_seg编译源文件将导致 warning C4073,而将文本初始化程序放置在库初始化区域中。根据MSDN:

Only third-party library developers should use the library initialization area, which is specified by #pragma init_seg. The following sample generates C4073...



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

为什么收到C4073警告?

最佳答案

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

这是更多信息:

假设您有一个自己的应用程序库。而且它有一些东西需要在其任何代码运行之前进行初始化,因为该库公开的某些类打算在您的应用程序代码中静态分配(或允许被静态分配),而这些类会做一些复杂的事情例如,在他们的构造函数中,需要一些大的预先计算(但不是静态)数据。因此,对于这些预先计算出的内容,您可以在一个类(另一个类)的构造函数中对其进行预先计算,然后静态分配该类的实例,以便该实例的初始化调用其构造函数来预先计算所有这些内容,而该静态实例用pragma init_seg(user)标记。现在,在您的任何应用程序代码运行之前(包括您代码中该库类的静态实例的任何构造函数),该库的init_seg(user)代码将全部运行,因此,当您对该库类的静态实例进行构造时,它们需要将在那里。

现在考虑确实必须提早解决的问题,您可以调用其中的静态实例。例如std::cout。您可以在自己具有静态实例的类的构造函数中在std::cout上调用方法。显然,对象std::cout需要在运行任何代码之前进行初始化。而且您的某些代码可能会在您标记为init_seg(user)的内容中运行。因此,Microsoft将所有此类代码(即std::cout等的构造函数)放置在init_seg(compiler)中。这些东西将首先运行。

那么init_seg(lib)的作用是什么?好吧,假设您是像MFC这样的框架。您公开了诸如Application对象之类的东西,用户将(可能希望)创建一个静态实例。 Application中将在静态初始化时运行的某些代码取决于MFC中需要初始化的其他内容。所以很明显,它需要被init_seg绑定(bind),但是在哪里? compiler仅适用于编译器和运行时,并且您的框架 Material (MFC)可能用于允许用户使用的init_seg(user)中,因此您可以在compileruser之间获得一个中间级别,即lib

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

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

而且,Microsoft(通常,大多数C++专家)会告诉您:如果存在某种顺序依赖性,则在静态初始化应用程序时需要初始化单独的库,那么您做错了。严重地。那里有一个设计问题。

因此,为了回应评论:这不是编译器错误。这是用户警告。相当良性:如果忽略它,一切都不会出错(不像说忽略从long到int的转换警告)。但是,如果您使用的是init_seg(lib),则您可能可能并不真正了解该编译器功能的全部内容,因此他们希望您考虑一下。在考虑之后,如果仍然要这样做,请关闭警告。

关于c++ - init_seg和库代码中的警告C4073?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32085048/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com