史蒂夫告诉我,VC 2015和VC 2017实际上(将要)二进制兼容.
我找到了零信息.这在2017年的发行说明(RC)中 - 或几乎在任何地方,所以这里是:
Visual Studio 2017 (v141)Visual Studio 2015 (v140)(*):是啊,其实我去进取,安装了2017年的RC,从我能在表面上看到的,至少在相同 MSVCRT被使用,这是msvcp140.dll和vcruntime140.dll(尽管平台工具集被称为"V141".
visual-studio visual-c++ visual-c++-2015 visual-studio-2017 visual-c++-2017
使用Visual Studio 2015 C++,14.0.25431.01更新3.我的代码中有意外行为.使用64位编译并运行,发布:
#include <iostream>
#include <stdint.h>
int main(int, char**) {
for (uint32_t i = 1; i < 3; ++i) {
uint32_t a = i * 0xfbd1e995;
uint64_t b = a;
std::cout << a << " 32bit" << std::endl;
std::cout << b << " 64bit" << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
我希望a和b有相同的值,但是当我运行此我得到这样的输出:
4224838037 32bit
4224838037 64bit
4154708778 32bit
8449676074 64bit
Run Code Online (Sandbox Code Playgroud)
看起来编译器用64位乘法取代了32位乘法.允许这样做,还是编译器错误?g ++和clang都给了我期望的数字.
编辑:我用更简单的版本更新我的代码有相同的问题.另外,我刚刚提交了一份错误报告.
template<typename ReturnT, typename... ParamT>
void foo(std::function<ReturnT(ParamT...)> callback)
{}
template<typename ReturnT, typename ParamT>
void bar(std::function<ReturnT(ParamT)> callback)
{}
main()
{
foo<int, int>([](int x){ return x; }); // no instance of function
// template matches argument list
bar<int, int>([](int x){ return x; }); // OK
}
Run Code Online (Sandbox Code Playgroud)
foo和bar之间的唯一区别是foo具有可变参数.不知何故,编译器能够将lambda转换为bar中的std :: function .
据我所知,模板类型推导不考虑类型转换.那么两个都不应该失败吗?
我在这个C++ 11代码上遇到编译错误,但我不知道为什么.这是代码:
#include <condition_variable>
class NonCopiableClass
{
std::condition_variable condition_;
};
struct NonCopiableStruct
{
std::condition_variable condition_;
};
class Test
{
public:
Test() :
myClass{},
myStruct{}
{};
private:
NonCopiableClass myClass;
NonCopiableStruct myStruct;
};
Run Code Online (Sandbox Code Playgroud)
Visual Studio 2015失败,出现以下错误:
错误C2280:'std :: condition_variable :: condition_variable(const std :: condition_variable&)':尝试引用已删除的函数1> c:\ program files(x86)\ microsoft visual studio 14.0\vc\include\mutex(550 ):注意:请参阅'std :: condition_variable :: condition_variable'的声明.
如果我更改Test constructor为不使用C++ 11统一初始化Struct它编译好了.
Test() :
myClass{},
myStruct() // <--- CHANGE
{};
Run Code Online (Sandbox Code Playgroud)
我没有得到为什么Struct类型使用复制构造函数,但Class似乎没问题.只有Struct拥有不可复制的成员才会发生这种情况.
我还注意到,如果我初始化成员初始化列表的Struct外部Test …
随着Microsoft在其最新版本中更改注册表项的模式,我如何检测是否在计算机上安装了Visual C++ 2017 Redistributable?
我的目标是安装VC++ 2015Redist,因为该软件是使用VS2015编写的.如果我能在一台机器上成功检测到VC++ 2017Redist,那么我跳过安装VC++ 2015Redist
redistributable visual-c++ vcredist visual-c++-2015 visual-c++-2017
重复:我正在寻找相同 Visual-C++版本的库之间的ABI兼容性!
我们希望混合和匹配来自不同团队的一些内部C++ DLL - 在不同时间使用不同的项目文件构建.由于构建时间较长,我们确实希望避免大型单片构建,其中每个团队重新编译另一个团队库的源代码.
当消耗C++的DLL 和C++的接口是相当 清楚 的是,你只能这样做,如果所有的DLL与相同的编译器/ Visual Studio的版本编译.
什么对我来说并不很明显是什么,到底需要是相同的,以获得ABI的兼容性.
_DEBUG)和release(NDEBUG)不能混合 - 但是这些链接到不同版本的共享运行时这一事实也很明显./O需要相同的开关 - 优化级别是否会影响ABI兼容性?(我很确定不会.)/EH开关?/volatile:ms|iso......?本质上,我想提出一组(元)数据来与描述它的ABI兼容性的Visual-C++ DLL相关联.
如果存在差异,我现在只关注VS2015.
几天前,我写了类似下面的内容:
struct A {
std::atomic_bool b = false;
};
Run Code Online (Sandbox Code Playgroud)
使用VC++ 2015编译器在Visual Studio 2015 Update 3中编译,没有出现任何错误.
现在我在Ubuntu上用GCC(5.4.0)重新编译了同样的东西并得到了错误:
使用已删除的函数'std :: atomic :: atomic(const std :: atomic&)
我在ideone上遇到了同样的错误,设置为C++ 14(不确定它使用的是什么编译器版本).
当然将代码更改为以下修复了gcc的问题:
struct A {
std::atomic_bool b { false };
};
Run Code Online (Sandbox Code Playgroud)
我的问题是:
1.谁是正确的(C++ 11兼容),VC++或GCC?似乎VC++从bool调用构造函数,而GCC调用复制构造函数(已删除).
2.为了在类声明中初始化原子的默认值,是正确初始化(上面)正确/首选方式吗?或者我应该使用ATOMIC_VAR_INIT宏(呃!)吗?
struct A {
std::atomic_bool b = ATOMIC_VAR_INIT(false);
};
Run Code Online (Sandbox Code Playgroud) 请考虑以下代码:
#include <cstddef>
class A
{
public:
struct B
{
int M;
};
static void StaticFunc();
};
void A::StaticFunc()
{
const std::size_t s0 = sizeof(::A::B::M);
const std::size_t s1 = sizeof(A::B::M);
const std::size_t s2 = sizeof(B::M);
}
int main()
{
const std::size_t s3 = sizeof(A::B::M);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
GCC编译它,只是警告未使用的变量.
但是,Visual C++ 2015无法使用以下代码编译它:
error C2326: 'void A::StaticFunc(void)': function cannot access 'A::B::M'
Run Code Online (Sandbox Code Playgroud)
就行了
const std::size_t s0 = sizeof(::A::B::M);
const std::size_t s1 = sizeof(A::B::M);
Run Code Online (Sandbox Code Playgroud)
在StaticFunc().
其他的线s2 = ...,并s3 …
我有一个简单的单成员结构,删除了复制结构/赋值,以及默认的移动构造/赋值.我试图通过值将这些结构中的一个传递给函数并返回该成员 - 非常简单.
struct NoCopy {
explicit NoCopy(int x) : x{x} {}
NoCopy(const NoCopy&) = delete;
NoCopy& operator=(const NoCopy&) = delete;
NoCopy(NoCopy&&) = default;
NoCopy& operator=(NoCopy&&) = default;
int x;
};
// noinline to ensure the crash is reproducible in release
// not required to reproduce the problem code
__declspec(noinline) int problem_function(NoCopy x) {
return x.x;
}
int main() {
return problem_function(NoCopy{ 1 });
}
Run Code Online (Sandbox Code Playgroud)
问题是当使用MSVC编译时,此函数崩溃.
查看反汇编,看起来当删除复制构造函数时,MSVC会尝试将其解释x为a NoCopy*,并且后续成员读取会导致分段错误.
这是一个godbolt的例子,用gcc和clang作为参考:https://godbolt.org/z/jG7kIw
请注意,gcc和clang都按预期运行.另请注意,这在优化和未优化的构建中都会发生,并且似乎会影响MSVC 2015和2017.
作为参考,我正在使用Visual Studio Professional 2015(14.0.25431.01 …
前提
我有一个包含不同VC++项目的Visual Studio 2015解决方案.
其中一些(EXE和一些DLL)将$ OutDir设置为默认值"$(SolutionDir)$(Configuration)\"(即"C:\ MySolution\Debug \").
对于其他一些项目(DLL),我需要将输出路径更改为"默认"$ OutDir的子目录(即"C:\ MySolution\Debug\Pieces \".
示例目录树:
C:\MySolution\Debug\
MyProgram.exe
Dependency.dll
.\Pieces\
MyPiece1.dll
MyPiece2.dll
约束
"Pieces"DLL取决于第三方Dependency.dll(通过NuGet包),我无法修改.
常用解决方案
通常的方法是更改"件"项目的$ OutDir项目设置,但这也会强制它们的依赖项在同一个子目录中输出.
这不是必需的,也会在调试和打包整个解决方案时产生问题.
到目前为止,
我尝试过:1.保持$ OutDir对所有项目都一样
2.将"pieces"$ TargetName更改为"Pieces\$(ProjectName)"
这似乎有效(两者都是MyPiece*.dlland依赖项. dll被正确放置并且调试很好),但不幸的是Visual Studio会生成以下警告:
警告MSB8012:TargetName(Pieces\MyPiece1.dll)与链接器的OutputFile属性值(MyPiece1)不匹配.这可能会导致您的项目错误地构建.要更正此问题,请确保$(OutDir),$(TargetName)和$(TargetExt)属性值与%(Link.OutputFile)中指定的值匹配.
这个警告有些令人困惑,因为项目设置中的%Link.OutputFile看起来是正确的:
$(OutDir)$(TargetName)$(TargetExt)=> C:\ MySolution\Debug\Pieces\MyPiece1.dll
问题
解决问题的正确方法是什么?
如何强制Visual Studio在不同的路径中输出一些生成的文件,但仍然在"默认"$ OutDir中具有Nuget依赖项?
我已经搜索过网络和StackOverflow,但我找不到合适的答案.
注意:我的问题与升级VS2010之前的解决方案无关(如Microsoft官方提示解决方案升级后警告MSB8012并在StackOverflow上询问).
visual-c++-2015 ×10
c++ ×6
visual-c++ ×4
c++11 ×3
64-bit ×1
abi ×1
class ×1
compiler-bug ×1
gcc ×1
stdatomic ×1
struct ×1
vcredist ×1
warnings ×1