标签: visual-c++-2015

Visual-C++ - 2017二进制兼容VC++ - 2015?

史蒂夫告诉我,VC 2015和VC 2017实际上(将要)二进制兼容.

我找到了信息.这在2017年的发行说明(RC)中 - 或几乎在任何地方,所以这里是:

  • 是一个用VC++构建的C++(C++接口)DLL - 2017与VC++ - 2015构建的DLL二进制兼容吗?
  • 2017和2015使用相同(动态)运行时库吗?
  • 如果是这样,Platform Toolset 和?之间的运行时区别是什么?(*)Visual Studio 2017 (v141)Visual Studio 2015 (v140)

(*):是啊,其实我去进取,安装了2017年的RC,从我能在表面上看到的,至少在相同 MSVCRT被使用,这是msvcp140.dllvcruntime140.dll(尽管平台工具集被称为"V141".

visual-studio visual-c++ visual-c++-2015 visual-studio-2017 visual-c++-2017

22
推荐指数
1
解决办法
5923
查看次数

将uint32_t转换为uint64_t导致不同的值?

使用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)

我希望ab有相同的值,但是当我运行此我得到这样的输出:

4224838037 32bit
4224838037 64bit
4154708778 32bit
8449676074 64bit
Run Code Online (Sandbox Code Playgroud)

看起来编译器用64位乘法取代了32位乘法.允许这样做,还是编译器错误?g ++和clang都给了我期望的数字.

编辑:我用更简单的版本更新我的代码有相同的问题.另外,我刚刚提交了一份错误报告.

c++ 64-bit visual-c++-2015

14
推荐指数
2
解决办法
1465
查看次数

如果模板没有可变参数,则将Lambda推导为std :: function

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)

foobar之间的唯一区别是foo具有可变参数.不知何故,编译器能够将lambda转换为bar中的std :: function .

据我所知,模板类型推导不考虑类型转换.那么两个都不应该失败吗?

c++ c++11 visual-c++-2015

12
推荐指数
2
解决办法
324
查看次数

成员初始化列表错误的统一初始化

我在这个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 …

c++ struct class c++11 visual-c++-2015

11
推荐指数
1
解决办法
476
查看次数

如何检测是否安装了Visual C++ 2017 Redistributable

随着Microsoft在其最新版本中更改注册表项的模式,我如何检测是否在计算机上安装了Visual C++ 2017 Redistributable?

我的目标是安装VC++ 2015Redist,因为该软件是使用VS2015编写的.如果我能在一台机器上成功检测到VC++ 2017Redist,那么我跳过安装VC++ 2015Redist

redistributable visual-c++ vcredist visual-c++-2015 visual-c++-2017

10
推荐指数
3
解决办法
9794
查看次数

使用来自不同时间/团队编译的同一VS的C++ DLL - ABI兼容性?

重复:我正在寻找相同 Visual-C++版本的库之间的ABI兼容性!

我们希望混合和匹配来自不同团队的一些内部C++ DLL - 在不同时间使用不同的项目文件构建.由于构建时间较长,我们确实希望避免大型单片构建,其中每个团队重新编译另一个团队库的源代码.

当消耗C++的DLL 和C++的接口相当 清楚 的是,你只能这样做,如果所有的DLL与相同的编译器/ Visual Studio的版本编译.

什么对我来说并不很明显是什么,到底需要是相同的,以获得ABI的兼容性.

  • 显然, debug(_DEBUG)和release(NDEBUG)不能混合 - 但是这些链接到不同版本的共享运行时这一事实也很明显.
  • 您是否需要完全相同的编译器版本,或者生成的DLL链接到同一共享 C++运行时是否足够- 也就是说,基本上是相同的可再发行组件?(我认为当传递完整的C++对象时静态不会飞)
  • 是否存在编译器(和链接器)选项的文档列表,这些选项需要相同才能兼容相同vc ++版本的两个C++ DLL?
    • 例如,是否/O需要相同的开关 - 优化级别是否会影响ABI兼容性?(我很确定不会.)
    • 或者两个版本都必须使用相同的/EH开关
    • 还是/volatile:ms|iso......?

本质上,我想提出一组(元)数据来与描述它的ABI兼容性的Visual-C++ DLL相关联.

如果存在差异,我现在只关注VS2015.

abi visual-c++ visual-studio-2015 visual-c++-2015

8
推荐指数
1
解决办法
538
查看次数

为什么Visual C++ 2015允许std :: atomic赋值?

几天前,我写了类似下面的内容:

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)

c++ gcc c++11 stdatomic visual-c++-2015

8
推荐指数
1
解决办法
874
查看次数

MSVC与GCC的行为不一致的sizeof

请考虑以下代码:

#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 …

c++ visual-c++ compiler-bug visual-c++-2015

7
推荐指数
1
解决办法
281
查看次数

MSVC将仅移动结构参数解释为指针

我有一个简单的单成员结构,删除了复制结构/赋值,以及默认的移动构造/赋值.我试图通过值将这些结构中的一个传递给函数并返回该成员 - 非常简单.

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 …

c++ visual-c++-2015 visual-c++-2017

6
推荐指数
1
解决办法
182
查看次数

如何设置vc ++项目的输出路径与其依赖项(nuget)不同?

前提
我有一个包含不同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上询问).

warnings visual-c++-2015

5
推荐指数
0
解决办法
103
查看次数