5
4

More than 5 years have passed since last update.

unsigned char('x') で関数形式の明示的型変換 Explicit type conversion (functional notation) が出来ない理由

Last updated at Posted at 2018-10-02

型名に () をつける関数スタイルのキャストで、MSVC でビルドできていた次のコードが gcc でエラーになると質問を受けました。

なぜコンパイルエラーになるのか即答できなかったので規格にあたりました。

#include <iostream>

int main()
{
        char c = 'a';
        auto uc = unsigned char(c);

        std::cout << uc << std::endl;
        return 0;
}
$ g++ -std=c++14 temp.cpp
temp.cpp: In function ‘int main()’:
temp.cpp:6:12: error: expected primary-expression before ‘unsigned’
  auto uc = unsigned char(c);
            ^~~~~~~~

結論

gcc が正しい。 MSVC は規格通りの挙動をしていない。

関数形式の明示的型変換

そもそも int x = int(0); のように 型名() の形式でキャストすることを関数形式の明示的型変換(Explicit type conversion (functional notation))と規格で呼んでいます。

C++14規格書(N4140) の 5.2.3 Explicit type conversion (functional notation) を見ると、

[C++11: 5.2.3/1]: A simple-type-specifier (7.1.6.2) or typename-specifier
(14.6) followed by a parenthesized expression-list constructs a value of 
the specified type given the expression list. 

とあり型名には simple-type-specifier か typename-specifier が使えると書いています。

typename-specifier は typename キーワードを使うのでここでは関係ありません。

つまり unsigned char は simple-type-specifier かどうかが焦点になります。

simple-type-specifier とは何かを調べてみると 7.1.6.2 に定義があります。

[C++11: 7.1.6.2/1]: The simple type specifiers are 
simple-type-specifier: 
    ...(省略)...
type-name:
    ...(省略)...
decltype-specifier:
    ...(省略)...

省略した定義部分には unsigned char はありません。また 7.1.6.2 の Table 10 - simple-type-specifiers and the types they specify には単数形ではない simple-type-specifier(s) の例として unsigned char が書かれています。

つまり unsigned charlong long は simple-type-specifier(s) であり simple-type-specifier ではないため関数形式の明示的型変換では使えません。

エラーになる gcc が正しいです。MSVC は妙な Microsoft 拡張をしてるんでしょう。

結局どうすれば?

MSVC を使わない

そもそも関数形式の明示的型変換を使わず static_cast を使う。

参考

cppreference: Declarations
https://en.cppreference.com/w/cpp/language/declarations

C++11の文法と機能(C++11: Syntax and Feature)
5.5.3 関数形式の明示的型変換(Explicit type conversion (functional notation))
http://ezoeryou.github.io/cpp-book/C++11-Syntax-and-Feature.xhtml#expr.type.conv

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4