LINUX.ORG.RU

Нубский вопрос об определении массива C++

 , ,


0

1

Почему?

#include <iostream>
#include <vector>
#include <array>

void foo(int a)
{
    size_t s;
    if (a < 1)  
        s = 100;
    else
        s = a;

    int sa[s]; // ок!
    std::cout << sizeof(sa) << std::endl; // размеры разные

    //std::array<int, s> a; // ошибка!
}

int main()
{
    foo(-1);
    foo(10);

    return 0;
}
Понятно, что C VLA имеет автоматическую длительность хранения и определяется по ходу выполнения в стеке. Что не так с C++ массивом? Зачем для него вычислять размер во время компиляции?



Последнее исправление: Rot1 (всего исправлений: 1)

С ним все так, просто размер std::array - шаблонный аргумент (тобишь времени компиляции)

yoghurt ★★★★★
()

< и > как бы намекают нам, что это шаблон, и инстанцироваться он будет на этапе компиляции. Стало быть, s должен быть известен на этапе компиляции. Поиграйся с constexpr, получишь то, что нужно

Deleted
()

А если в отдельной единице трансляции?

Сдаётся мне - он её просто встраивает, даже вроде как право имеет.

pon4ik ★★★★★
()

Понятно, что C VLA имеет автоматическую длительность хранения и определяется по ходу выполнения в стеке.

Не используй vla. Это опасная гадость.

Что не так с C++ массивом?

С ним всё так. Знать размер во время компиляции нужно, чтобы отсеять ошибки и провести оптимизации. Нужен динамический массив - бери вектор.

Ivan_qrt ★★★★★
()

int sa[s]; // ок!

За щёку **ёк.

prog.cc: In function 'void foo(int)':
prog.cc:13:13: error: ISO C++ forbids variable length array 'sa' [-Wvla]
   13 |     int sa[s]; // ок!
      |             ^
anonymous
()
Ответ на: комментарий от anonymous
$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --enable-libmpx --with-system-zlib --with-isl --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --enable-gnu-indirect-function --enable-multilib --disable-werror --enable-checking=release --enable-default-pie --enable-default-ssp --enable-cet=auto
Thread model: posix
gcc version 8.2.1 20180831 (GCC)

:!g++ main.cpp && ./a.out
Rot1
() автор топика
Ответ на: комментарий от Deleted

Точно! Тем не менее, получается очень неудобно в таких ситуациях...

std::vector<int> v {1, 2, 3};

int ca[v.size()];
//copy(begin(v), end(v), std::begin(ca));
for (int i = 0; i < v.size(); ++i)
    ca[i] = v[i];
Rot1
() автор топика
Ответ на: комментарий от anonymous

Это да. Я читал, что они недопустимы стандартом

Rot1
() автор топика

Так это ж шаблон. Как уже выше говорили, используйте constexpr, если компилятор поддерживает.

Meyer ★★★★★
()
Ответ на: комментарий от Rot1

Точно! Тем не менее, получается очень неудобно в таких ситуациях...

Угу. В особенности когда v внезапно вырастает до сотни метров. Очень неудобно получается.

Ivan_qrt ★★★★★
()

Зачем от тебе нужен? по стандарту он запрещен, а слишком большие массивы могут еще и прогу ронять причем потом не с первого разу догадаешься что происходит. new delete - true way :)

LinuxDebian ★★★★
()
Ответ на: комментарий от Deleted

тогда какой заголовок лучше: этот

template<size_t num> std::array<Response, num> get_request(const std::array<std::string, num> &urls);
или этот
std::vector<Response> get_request(const std::vector<std::string> &urls);
?

Мне кажется, что первый очевидней, так как гарантирует, что ответов будет столько же, сколько и запросов. Так ведь?

Rot1
() автор топика
Последнее исправление: Rot1 (всего исправлений: 1)
Ответ на: комментарий от Rot1

Откуда мне знать, что в твоей программе будет лучше?

Первый гарантирует, что «количество ответов» будет известно на этапе компиляции.

Deleted
()

Прочитай какую-то книгу по C++

Ну пипец же...

fornlr ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.