C++可以用变量定义数组了么 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dekira
V2EX    C

C++可以用变量定义数组了么

  •  
  •   dekira 2017-10-23 11:07:04 +08:00 4230 次点击
    这是一个创建于 2913 天前的主题,其中的信息可能已经有所发展或是发生改变。

    偶然发现 c++可以用变量定义数组了... 这是为啥?新的标准么?求解答

    Clion,Ubuntu,支持 c++11,其他见图吧!......然而不能发图!

    32 条回复    2017-10-25 11:46:49 +08:00
    missdeer
        1
    missdeer  
       2017-10-23 11:08:46 +08:00
    然而图呢?
    GeruzoniAnsasu
        2
    GeruzoniAnsasu  
       2017-10-23 11:10:53 +08:00
    dekira
        3
    dekira  
    OP
       2017-10-23 11:14:00 +08:00
    图来了......

    sagaxu
        4
    sagaxu  
       2017-10-23 11:14:43 +08:00
    18 年前 C 语言就可以这么做了,但是 C++一直没有支持 VLA,因为 C++有 vector 和 array
    mainjzb
        5
    mainjzb  
       2017-10-23 11:16:59 +08:00
    C99 早就支持了
    araraloren
        6
    araraloren  
       2017-10-23 11:17:08 +08:00
    c++ 就一直没支持过
    c 有一个标准必选支持,最新的标准已经变成可选的了
    coordinate
        7
    coordinate  
       2017-10-23 11:18:59 +08:00
    C99 中数组大小运行时刻确定,另外可变长数组的维数在数组生存期内是不变的。
    wevsty
        8
    wevsty  
       2017-10-23 11:20:30 +08:00
    对 C 来说,C99 允许定义变长数组,然而有些编译器一直不肯支持(没错,说的就是你 MSVC )。
    对 CPP 来说,变长数组这个特性标准上就没有支持,而且更 cpp 的做法是使用 vector 这样的 STL 容器。
    northisland
        9
    northisland  
       2017-10-23 11:23:05 +08:00
    编译器的问题。记得很久以前折腾 codeblocks 可以通过,msvc 不行。

    比较恶心的问题,最好不用
    nullcoder
        10
    nullcoder  
       2017-10-23 11:24:12 +08:00
    @wevsty 变长数组和变量定义数组长度不是一个意思吧
    wevsty
        12
    wevsty  
       2017-10-23 11:35:29 +08:00
    @nullcoder
    不用太纠结字面的说法。
    变长数组通常用来指代的是能直接用变量来定义数组的这种特性。
    malloc 或者 new 出来的一个空间也可以当成数组用,这样也确实实现了变量来定义数组这种事实。
    一定要纠结的话,可以理解为变长数组是用变量定义数组长度的一个子集。
    justou
        13
    justou  
       2017-10-23 11:40:23 +08:00
    编译期常量定义数组大小(c++11)
    constexpr int a = 10;
    int b[2 * a] = { 0 };

    C99 标准开始似乎才有这种变长数组写法
    void f(size_t a){
    int arr[a];
    ...
    }
    因为是分配在栈上的, 所以用得不对直接炸栈
    soli
        14
    soli  
       2017-10-23 11:45:13 +08:00
    C99 已经支持了。
    C++98 和 C++11 的时候,gcc 是以扩展的形式支持的;
    本来有望在 C++14 标准中支持,但讨论了半天,最后还是被砍掉了
    ( gcc 都脱了裤子上了,C++14 正式出来之后又把裤子穿上了)。

    所以,现在 gcc 还是以扩展的形式支持,就和 C++98、C++11 的时候一样。

    ## GCC 4.9 的发布说明

    > G++ supports C++1y variable length arrays. G++ has supported GNU/C99-style VLAs for a long time, but now additionally supports initializers and lambda capture by reference. In C++1y mode G++ will complain about VLA uses that are not permitted by the draft standard, such as forming a pointer to VLA type or applying sizeof to a VLA variable. Note that it now appears that VLAs will not be part of C++14, but will be part of a separate document and then perhaps C++17.


    ## GCC 5 的发布说明

    > G++ no longer supports N3639 variable length arrays, as they were removed from the C++14 working paper prior to ratification. GNU VLAs are still supported, so VLA support is now the same in C++14 mode as in C++98 and C++11 modes.

    ## 上面提到的 N3639

    [N3639]( http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3639.html)
    chiu
        15
    chiu  
       2017-10-23 11:45:52 +08:00 via Android
    C99 就支持了
    lrxiao
        16
    lrxiao  
       2017-10-23 11:49:56 +08:00
    VLA 有 security 问题。。C11 已经是 optional 了。。标准只存在于 C99 C++根本没支持过..
    liuminghao233
        17
    liuminghao233  
       2017-10-23 13:13:24 +08:00 via iPhone
    这样定义并不是数组 而是指针吧
    introom
        18
    introom  
       2017-10-23 13:17:26 +08:00 via Android   1
    你开 Wall Wextra pedantic ,总会告诉你哪里有问题吧
    luoqeng
        19
    luoqeng  
       2017-10-23 13:27:32 +08:00
    叫柔性数组吧
    allinwonder
        20
    allinwonder  
       2017-10-23 15:02:38 +08:00 via iPhone
    C++ 的标准真是越来越庞大而臃肿,简直离人类能用越来越远了
    RLib
        21
    RLib  
       2017-10-23 17:52:07 +08:00
    用 alloca 不就好了
    yingtl
        22
    yingtl  
       2017-10-23 18:36:08 +08:00
    @lrxiao 具体是什么 security 呢? 检查长度能避免么
    sumless
        23
    sumless  
       2017-10-23 19:04:04 +08:00
    你这个应该是被编译器优化了,你可以看一下编出来的汇编代码,肯定是直接把变量 a 给省略了。
    你把你的测试代码改成这样试试:写一个子函数,传入 int a 这个参数来决定数组大小,这时候编译器就不知道要分配多大了。
    dekira
        24
    dekira  
    OP
       2017-10-23 20:00:23 +08:00
    @sumless 子函数也可以
    lrxiao
        25
    lrxiao  
       2017-10-23 21:03:34 +08:00
    @yingtl 可以 那为什么不直接开 T arr[10000]呢 VLA 实际上会编译出来一坨代码

    https://stackoverflow.com/questions/1887097/why-arent-variable-length-arrays-part-of-the-c-standard

    同样 alloca 也不推荐
    htfy96
        26
    htfy96  
       2017-10-24 07:47:30 +08:00
    @allinwonder #20 然而这是 20 年前的 C 的 feature GNU coreutils 经常用
    visionsmile
        27
    visionsmile  
       2017-10-24 09:33:26 +08:00
    @luoqeng #19 柔性数组是这样,而且也是 C 里特有的东西:

    ```cpp
    struct A{
    char tag;
    char alz[];
    };
    ```

    详见:[Array of length zero]( https://imzlp.me/posts/21095/)
    yingtl
        28
    yingtl  
       2017-10-24 14:37:42 +08:00
    @lrxiao 我还以为这个实现挺简单的呢。看看有没有空间挪动个栈指针就行了呢。 怎么会有一坨代码呢
    yingtl
        29
    yingtl  
       2017-10-24 15:09:00 +08:00
    @lrxiao 不用一个很大的普通的栈上的数组是因为当需要多个这样数组的时候可能造成很多“空隙”, 太多的话就爆了
    lrxiao
        30
    lrxiao  
       2017-10-24 22:18:33 +08:00
    yingtl
        31
    yingtl  
       2017-10-25 09:33:40 +08:00
    lrxiao
        32
    lrxiao  
       2017-10-25 11:46:49 +08:00
    @yingtl 你这个例子没用到 arr 所以比较简单 实际上应该都会插入检查栈空间的汇编
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2967 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 14:10 PVG 22:10 LAX 07:10 JFK 10:10
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86