简体   繁体   English

如何在VS2017中不使用/ Za编译一个文件(使用/ Za编译其余文件)?

[英]How can I compile one file without /Za (and the rest with /Za) in VS2017?

I want to be able to compile my VS2017 C++ project without Microsoft's language extension shenanigans. 我希望能够在不使用Microsoft语言扩展名的情况下编译VS2017 C ++项目。

Based on the replies here, /Za compiler directive does not compile system headers in VS2010 , is there a way to make VS compile one file without /Za, and the rest with? 根据这里的答复, / Za编译器指令不会在VS2010中编译系统头文件 ,是否有办法使VS编译一个不带/ Za的文件,而其余的带/ Za呢?

The file that doesn't like the /Za flag in particular is Winnt.h, and several of my files are using it. 特别不喜欢/ Za标志的文件是Winnt.h,我的一些文件正在使用它。

According to the Visual Studio devs: 根据Visual Studio开发人员的说法

The compiler switch /Za was an effort started decades ago to carve out a strictly portable behavior across several C++ compilers. 编译器开关/ Za是数十年前开始的一项工作,旨在在多个C ++编译器之间实现严格的可移植行为。 The effort was stalled and we no longer recommend it for new projects. 这项工作已停止,我们不再建议将其用于新项目。 The switch /Za does not support certain key Microsoft SDK header files. 开关/ Za不支持某些关键的Microsoft SDK头文件。 By contrast /permissive- offers a useful conformance mode where input C++ code is interpreted according to ISO C++ rules but also allows conforming extensions necessary to compile C++ on targets supported by Visual C++. 相比之下,/ permissive-提供了一种有用的一致性模式,其中输入的C ++代码根据ISO C ++规则进行解释,但是还允许在Visual C ++支持的目标上编译C ++所需的一致性扩展。 For example, you can use /permissive- with C++/CLI. 例如,您可以将/ permissive-与C ++ / CLI一起使用。 The compiler switch /Za rejects a few non-conforming constructs; 编译器开关/ Za拒绝一些不合格的构造; however the compiler switch /permissive- is our recommendation going forward for conforming code. 但是,我们建议继续使用编译器开关/ permissive-以使代码一致。

Therefore, compiling the whole project with /permissive- instead of trying to implement exceptions to single translation units using /Za might be an acceptable payoff between being conformant to ISO-C++ and being able to compile non-standard Microsoft header files. 因此,使用/permissive-编译整个项目,而不是尝试使用/Za对单个翻译单元实施例外,这可能是在符合ISO-C ++与能够编译非标准Microsoft头文件之间/Za一项可接受的回报。 Furthermore, you can disable more extensions by making use of the /Zc flag and its options: 此外,您可以通过使用/Zc标志及其选项来禁用更多扩展名:

The compiler switches /Zc:strictStrings and /Zc:rvalueCast are currently off by default, allowing non-conforming behavior. 当前,默认情况下,编译器开关/ Zc:strictStrings和/ Zc:rvalueCast处于关闭状态,从而允许出现不一致的行为。 The switch /permissive- turns them on by default. 开关/ permissive-默认情况下将其打开。 You can pass in the /Zc flags after /permissive- to override this behavior if needed. 如果需要,可以在/ permissive-之后传递/ Zc标志以覆盖此行为。

This was painfully simpler than I realised. 这比我意识到的要简单得多。

  1. Right click the project in Solution Explorer, go to Properties -> C\\C++ -> Language -> Disable Language Extensions -> Yes (/Za) 右键单击解决方案资源管理器中的项目,转到“属性”->“ C \\ C ++”->“语言”->“禁用语言扩展”->“是(/ Za)”
  2. Hit OK. 点击确定。

Now whatever new files you add will use /Za. 现在,无论您添加什么新文件,都将使用/ Za。

  1. Hold Shift and select all the files you need to not use /Za. 按住Shift键,选择你所需要的使用/ Za -的文件。
  2. Repeat Step 1 except now set Disable Language Extensions to No. 重复步骤1,但现在将“禁用语言扩展”设置为“否”。

Now only those files will build with Microsoft's language extensions. 现在,只有那些文件将使用Microsoft的语言扩展名构建。

No mucking around with vcxproj editing (and the filters hassle it creates), no having to set files to stop inheriting from project defaults, no messing with /Ze or /Zc or any manual command line jimmying. 无需进行vcxproj编辑(以及由此产生的过滤器麻烦),无需设置文件以停止从项目默认值继承,也无需弄乱/ Ze或/ Zc或任何手动命令行混乱。 The amount of time I wasted not realising how simple this was. 我浪费的时间没有意识到这是多么简单。 >_< > _ <

A few other notes: Thanks to the suggestions here and pushing & pulling various levers, I have found the following: 其他一些注意事项:由于这里的建议以及推拉各种杠杆的作用,我发现了以下几点:

  • The /permissive- command line option, discussed on the Visual C++ Team Blog (thanks Jodocus) apparently does what I needed. Visual C ++ Team Blog (感谢Jodocus)上讨论的/ permissive-命令行选项显然可以满足我的需求。 However I found it simply didn't catch an anonymous struct, so perhaps I've done something wrong but it wasn't forcing my code into ISO C++ conformance. 但是我发现它根本没有捕获匿名结构,所以也许我做错了什么,但是并没有强迫我的代码符合ISO C ++的要求。

  • The /Zc compiler options don't mention anonymous structures, so if one of them catches non-conforming anonymous structs, I can't tell which. / Zc编译器选项没有提及匿名结构,因此,如果其中之一捕获了不合格的匿名结构,我将无法分辨。 Since that's one thing from ISO C++ I can't find explicitly covered, I lost faith in these flags also. 由于这是ISO C ++的一件事,我无法明确地进行介绍,因此我也对这些标志失去了信心。

  • If the offending file is a header file, you have to disable that /Za for every source file that includes that offending header. 如果有问题的文件是头文件,则必须为每个包含有问题的头文件的源文件禁用/ Za。

  • Finally, this can also be done programmatically instead. 最后,这也可以通过编程来代替。 See DisableLanguageExtensions . 请参阅DisableLanguageExtensions

Technically speaking, this is how you assign some metadata to a whole group of files, but ignore it in one file using MSBuild: 从技术上讲,这是将一些元数据分配给整个文件组的方法,但是使用MSBuild在一个文件中将其忽略:

 <ItemGroup> <Compile Include="**\\*.cpp" Exclude="foo.cpp"> <SomeCompilerSettingMetaData>/Za</SomeCompilerSettingMetaData> </Compile> <Compile Include="foo.cpp" > <SomeCompilerSettingMetaData></SomeCompilerSettingMetaData> </Compile> </ItemGroup> 

I don't remember what compiler setting /Za will get assigned to, and it doesn't matter for the purposes of this illustration. 我不记得将/ Za分配给哪个编译器设置,对于此插图而言,这并不重要。 The point is the Include and Exclude attributes on the Items list should exclude and include the file you want to single out for special settings. 关键是“项目”列表上的“ 包括”和“ 排除”属性应排除并包括您要针对特殊设置而单独列出的文件。 Notice in the last one that the compiler setting you are looking at is absent. 请注意,在最后一个中,缺少正在查看的编译器设置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM