Здравствуйте, _NN_, Вы писали:
_NN>Статический анализатор MSVC ругается на две последние функции но не ругается на предыдущие. _NN>Очевидно правила типов работают немного по другому во времени компиляции.
Я так подозреваю, что компиляторы вычисляют константы на этапе компиляции и видят, что результат не выходит за пределы предствавления unsigned short, поэтому предупреждать не нужно.
Попробуйте объявить вместо int l[5], скажем int l[70000].
_NN>Это правильно по стандарту ?
ЕМНИП warning'и стандартом не описываются.
Статический анализатор MSVC ругается на две последние функции но не ругается на предыдущие.
Очевидно правила типов работают немного по другому во времени компиляции.
Это правильно по стандарту ?
#include <algorithm>
#include <type_traits>
static_assert(std::is_same_v< decltype(sizeof(1)), size_t >);
static_assert(std::is_same_v< decltype(static_cast<unsigned short>(1) + sizeof(1)), size_t >);
int f_countof(unsigned short i)
{
int l[5] = { 1,2,3,4,5 };
unsigned short j = i + sizeof(l) / sizeof(l[0]); //return j;
}
int f_countof_with_cast(unsigned short i)
{
int l[5] = { 1,2,3,4,5 };
unsigned short j = i + static_cast<size_t>(sizeof(l) / sizeof(l[0]));
return j;
}
int f_countof_with_constexpr(unsigned short i)
{
int l[5] = { 1,2,3,4,5 };
constexpr size_t q = static_cast<size_t>(sizeof(l) / sizeof(l[0]));
unsigned short j = i + q;
return j;
}
int f_countof_with_const(unsigned short i)
{
int l[5] = { 1,2,3,4,5 };
const size_t q = static_cast<size_t>(sizeof(l) / sizeof(l[0]));
unsigned short j = i + q;
return j;
}
int f_countof_with_var(unsigned short i)
{
int l[5] = { 1,2,3,4,5 };
size_t q = static_cast<size_t>(sizeof(l) / sizeof(l[0]));
unsigned short j = i + q; // warning C4267: 'initializing': conversion from 'size_t' to 'unsigned short', possible loss of datareturn j;
}
int f_std_size(unsigned short i)
{
int l[5] = { 1,2,3,4,5 };
unsigned short j = i + std::size(l); // warning C4267: 'initializing': conversion from 'size_t' to 'unsigned short', possible loss of datareturn j;
}
Опытным путём выяснилось , что переменная const/constexpr так же как и sizeof не вызывает проблем у статического анализатора:
template <typename T>
const size_t S = 0;
template <typename T, size_t N>
const auto S<T[N]> = N;
// Или
// template <typename T, size_t N>
// constexpr size_t S<T[N]> = N;void f()
{
int q[] = { 1 };
[[maybe_unused]] unsigned short a = S<decltype(q)>; // OK
}
Однако в случае с функцией фокус не проходит:
constexpr size_t w() { return 1; }
constexpr size_t e = 1;
void g()
{
[[maybe_unused]] unsigned short a = e; // OK
[[maybe_unused]] unsigned short b = w(); // conversion from 'size_t' to 'unsigned short', possible loss of data
}
Такой вариант не работает потому как std::size возвращает size_t и всё выражение снова получает тип size_t.
Здравствуйте, _NN_, Вы писали:
_NN>Есть идеи как для массивов использовать переменную, а в остальных случаях функцию ?
Я не совсем понимаю, что вы пытаестесь сделать и зачем. Если у вас функция возвращает size_t, то без знания возможных пределов возвращаемого значения в unsigned short результат её выполнения присваивать нельзя. А если пределы известны, то почему просто не сделать static_cast<unsigned short>(::std::size(c))? И вообще, зачем unsigned short ? Это попытка сэкономит пару байтов на стеке?
Здравствуйте, B0FEE664, Вы писали:
_NN>>Есть идеи как для массивов использовать переменную, а в остальных случаях функцию ?
BFE>Я не совсем понимаю, что вы пытаестесь сделать и зачем. Если у вас функция возвращает size_t, то без знания возможных пределов возвращаемого значения в unsigned short результат её выполнения присваивать нельзя. А если пределы известны, то почему просто не сделать static_cast<unsigned short>(::std::size(c))? И вообще, зачем unsigned short ? Это попытка сэкономит пару байтов на стеке?
Это попытка усмирить статический анализатор.
Есть C API принимает unsigned short.
Если писать f(sizeof(a)) то нет проблем, а вот f(std::size(a)) ругается.
Пока решил через функцию выбирающую минимальный тип через if constexpr.
Здравствуйте, Alexander G, Вы писали:
AG>Перегрузки с разными возвращаемыми типами:
В общем выяснилось, что анализатор не умеет делать подстановки constexpr функций и всегда жалуется, а с переменными умеет.
Похоже фичу в язык добавили, а обвязку вокруг забыли.