автоматически вычитаемый тип из sizeof отличается в Visual Studio C ++ и GCC - PullRequest
0 голосов
/ 14 марта 2019

Я немного потерян здесь.

В моем коде мне нужно иметь unsigned int в качестве ссылки для вызова функции Rfc из SAP Netweaver, размер буфера, который я даю этой функции.

В моей среде VS я программирую:

auto buffer_length = sizeof(buffer);
auto rc = RfcCall...(..., &buffer_length, ...)

Это прекрасно компилируется и зависает над параметром buffer_length, которое показывает, что это действительно целое число без знака.

Точно такой же код, скомпилированный с GCC 4.8.5, выдает ошибку компилятора - оказывается, что моя переменная имеет тип int там.

Но почему? И что я могу сделать, чтобы предотвратить это? Я думал, что есть стандарты, чтобы придерживаться ...: (

Ответы [ 2 ]

2 голосов
/ 17 марта 2019

В соответствии с §18.2p6 [support.types]:

Тип size_t является целочисленным типом без знака, определяемым реализацией, который достаточно большой, чтобы содержать размер в байтах любого объекта.

И §5.3.3p6 [expr.sizeof]:

Результат sizeof и sizeof... является константой типа std::size_t.

Итак, по стандарту sizeof(buffer) является целым типом без знака .Либо есть ошибка в GCC (что маловероятно, поскольку std::size_t равно unsigned long), либо ваша ошибка не там, где вы думаете.

0 голосов
/ 14 марта 2019

Перефразируя стандарт ISO, cppreference дает:

sizeof () возвращает значение std :: size_t, которое определено стандартом как

typedef /*implementation-defined*/ size_t;

Единственная гарантия, которую вы имеете, заключается в том, что

std :: size_t может хранить максимальный размер теоретически возможного объекта любого типа (включая массив).

Это поддерживает по крайней мере до C ++ 11, ISO C ++ откладывает определение std :: size_t до ISO C, что, в свою очередь, переносит его в компилятор.У меня Visual Studio 2015, поэтому он находится в vcruntime.h, где определением является

#ifdef _WIN64
    typedef unsigned __int64 size_t;
...
#else
    typedef unsigned int     size_t;

C ++ 11 добавлены целочисленные типы фиксированной ширины, такие как std::uint64_t, который гарантированно равен 64целое число без знакаЗатем вы можете использовать static_cast<std::uint64_t>(sizeof(buffer)), чтобы преобразовать его перед присваиванием.

...