Gaming Life

一日24時間、ゲームは10時間

VS 16.7以前では一時オブジェクトのアドレスを&演算子で取得してもエラーが出なかったらしい

Visual Studio 2019のバージョンを16.8に上げてから、DirectX12のコードをビルドしてみたら、これまでコンパイルできていたものができなくなっていた。そのコードがこれ。

hr = m_device->CreateCommittedResource(
            &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), // ここでC2102エラー
            D3D12_HEAP_FLAG_NONE,
            &depthBufferDesc,
            D3D12_RESOURCE_STATE_DEPTH_WRITE,
            &depthClearValue,
            IID_PPV_ARGS(&m_depthBuffer)
        );

docs.microsoft.com

C2102: '&'に左辺値がありません。

エラーの原因は、一時オブジェクト(右辺値)である CD3DX12_HEAP_PROPERTY のアドレスを、&演算子で取得しようとしたこと。よく考えれば、一時オブジェクトのアドレスを取得なんてしてはいけないことだと思う。なので、試しに他のコンパイラで似たようなコードを書いてみた。

#include <iostream>

struct A { int a, b, c, d; };

A make_A() { return A{}; }

void func(A*) {}

int main() {
    func(&(A{}));
    func(&make_A());
}

wandbox.org

gccでもclangでも、このコードはコンパイル出来なかった。右辺値のアドレスを取ろうとするのは駄目みたい。

で、MSVCのオンラインコンパイルも可能な、Compiler Explorerでも同じコードをコンパイルしてみた。すると、MSVCだけコンパイルが通ることが確認できた。

godbolt.org

どうもVisual Studioが間違っていて、バージョン16.8からコンパイルが通るようになったみたい。

ちなみに手元で試した限り、Visual Studio 2017では、このコードのコンパイルが通った。