再探C++数组的size可以是变量

学生在QQ群中贴图:

他说:“老师这个不报错。”

细看,定义数组时:

int a;
cin>>a;
int A[a];

这不科学,定义数组时,元素个数用变量,没有这么玩的!

有人跟上了:“我一直这么用!”

这还了得,十几年的修行,就这么塌了。C和C++一直在规定数组定义时,元素个数必须能确定。作为人工语言,就这么规定的,也在各种编译器中得到了贯彻。

学生猜测:“CodeBlocks 13.12的新支持?”

我只能先澄清:“不是13.12的事。codeblocks给了个壳,编译的活是gcc干的。难道是某版本gcc放松要求了?苦逼的计算机老师,就这么被坑了。谁查查资料,考证一下。搞清楚前,即使允许,也按规矩来。”

晚上睡不着,自己查一查。居然找出去年我发的博文《初探C++数组的size可以是变量》,当时在WalterSavitch的《C++程序设计(第8版)》中查到“数组长度使用变量,对大多数编译器是非法的。”在举例中提到“有的编译(但并非全部)允许用变量指定数组长度。但是为了移植性,不应该这样做,即使目前所用的编译器允许。”

这算是一个解释。

记吃不记打。去年的学生提到过的问题,我做过初探,居然也忘记了。

菜鸟的优秀品质就在于由于不知而无畏,可以撞到各种错。这实际上,是原生学习力中的重要部分。一个有程序设计功底的人,看了书上讲的,会很快理解,并自觉不去这样做。这样的问题,不会由有经验者发现。

为和菜鸟们厮混而自豪。

今年想将工作推进一步。查了ISO/IEC14882(C++语言的国际标准)在1998年和2011年出的两个版本,在8.3.4小节都强调了定义数组时,要用常量!

写了下面的程序,在CodeBlocks13.12下调试,编译器是GCC 4.7.1。

#include<iostream>
using namespace std;
int main( )
{
    int n;
    cin>>n;
    int a[n];
    for(int i=0; i<n+2; i++)
        a[i]=i;
    for(int i=0; i<n+5; i++)
        cout<<a[i]<<" ";
    return 0;
}

居然连个警告都没有!

还让不让人教C++了。学院在改培养方案,明年不会给大一的教C++了,教C。

再查,说这种宽松是由C99而来的。找到ISO/IEC 9899:TC2(C语言标准)6.7.5.2小节中,果然有这样的规定。

决定不再考证。如何在CodeBlocks中让这样的程序不能通过呢?

改设置。

找CodeBlocks13.12的菜单setting->Compiler...,

打勾的设置要求用严格的ISO标准提出警告。

再编译程序,终于来了警告:

D:\CPP\codeBlock\example\main.cpp|7|warning: ISO C++ forbids variable length array ‘a‘ [-Wvla]|

再想让报出错来,没有找到设置。换一种编译器,一定能得逞。不折腾了。

想知道,在企业中是如何处理这件事情的。找到了《Google C++ 编程规范.pdf》,下面是截图:

我不知道所谓变长数组的确切定义,但是启示却很明白,老老实实地按常规写程序。在这方面,不必紧跟放松了的规定。

??

时间: 2024-10-13 05:01:36

再探C++数组的size可以是变量的相关文章

【再探JNI】

上一次了解了一点JNI,然后不甘心的找到了JNI的官方文档.(官方文档绝对是一个最好的学习资料),百度找出来的一些资料大多数是比较零零碎碎的,不具有系统学习的可能,对于我这样的初学者,先全面的了解一个技术比往一个死角里钻研要好很多.并且百度出来的部分资料估计就是跟我这样的半吊子水平还不到的人的一些心得体会呢.因此,个人建议是看官方文档去全面了解一项技术,然后不理解的地方去再去搜集资料.加上自己的理解和实践,这样会进步的快一点. 好了,闲话少说.进入今天的真题.<再探JNI> (1)什么时候用J

再探oVirt-配置一个2节点的ovirt环境

日期:2015/11/4 - 2015/11/5 主机:engine, node01, node02 目的:再探oVirt-配置一个2节点的ovirt环境 操作内容: 一.基础操作 1.资源 ovirt engine: engine ovirt node: node01, node02 2.hosts 10.50.200.141 engine.ovirt 10.50.200.101 n101.ovirt 10.50.200.102 n102.ovirt 3.防火墙放行同一个局域网内的访问限制 后

通过Android源码分析再探观察者模式(二)

接着上篇文章,现在在通过Android实际开发和源码再探观察者模式,listview是我们日常开发中必用的控件,虽然之前就有listview的替代品(recyclerview),现在不去深究两个控件到底谁好谁差,但有一点需要强调下,它们之间有一大相同点,都是通过观察者模式去实现数据更新. 首先,我们先去看一个简单的例子 /** * * created by zero on2016-6-1 * * 通过listview再探观察者模式 * */ public class MainActivity e

ViewPager+Fragment再探:和TAB滑动条一起三者结合

Fragment前篇: <Android Fragment初探:静态Fragment组成Activity> ViewPager前篇: <Android ViewPager初探:让页面滑动起来> <Android ViewPager再探:增加滑动指示条> 这篇算是对之前学习写下的3篇博客知识总结吧~ 程序的总体结构如下: (其中listview.xml为测试项,可忽略) 其中,layout1对应Fragment1,以此类推:layout1中有listview,layout

再探使用kubeadm部署高可用的k8s集群-01引言

再探使用kubeadm部署高可用的k8s集群-01引言 2018/1/26 提示 仅供测试用途前言:高可用一直是重要的话题,需要持续研究.最近关注到 k8s 官网文档有更新,其中一篇部署高可用集群的文章思路不错,简洁给力,希望能分享给有需要的小伙伴一起研究下. 资源 k8s node master0, 10.222.0.100 master1, 10.222.0.101 master2, 10.222.0.102 LB, 10.222.0.88 master0, master1, master2

再探Redux Middleware

前言 在初步了解Redux中间件演变过程之后,继续研究Redux如何将中间件结合.上次将中间件与redux硬结合在一起确实有些难看,现在就一起看看Redux如何加持中间件. 中间件执行过程 希望借助图形能帮助各位更好的理解中间件的执行情况. redux如何加持中间件 现在是时候看看redux是如何将中间件结合了,我们在源码中一探究竟. * @param {Function} [enhancer] The store enhancer. You may optionally specify it

再探Linux动态链接 -- 关于动态库的基础知识

  在近一段时间里,由于多次参与相关专业软件Linux运行环境建设,深感有必要将这些知识理一理,供往后参考. 编译时和运行时 纵观程序编译整个过程,细分可分为编译(Compiling,指的是语言到平台相关目标文件这一层次)和链接(Linking,指目标文件到最终形成可执行文件这一层次),这个总的过程可称为编译时:就动态链接而言,还存在一个运行时,即程序在被操作系统加载的过程中,系统将该程序需要的动态库加载至内存到程序开始运行的这一段过程.明确这两个过程在一般linux开发中的地位,以及了解每个"

再探css3

再探css3 我们知道,这几年来智能手机的高速发展使得人们使用移动端上网的时间和人数已经超过了PC端.例如在2015年,就中国电商而言,各电商平台在移动端持续发力,移动端购物占比不断攀升,双11期间,天猫交易额突破912亿元,其中移动端交易额占比68%,京东移动端下单量占比达到74%,其余各大电商平台移动端的支付比例也在60%-80%之间.即移动端在2015年超越PC端,成为网购市场的主流选择.这也使得网页设计师需要更加注重移动端的网页制作,而移动端对于HMTL5和CSS3目前已经支持的非常好了

再探 butterfly.js - grunt.js篇(一)

再探 butterfly.js - grunt.js篇(一) 神器 grunt.js 久仰grunt.js的大名,学习grunt.js一直是我todo List的第一位.趁着新春佳节来临之际(打酱油的日子),就来填了这个坑,完了这个心愿. grunt.js的强大,强大在于它拥有很多用途丰富的插件,和不同插件之间的联动实现更牛逼的功能. 这里默认大家已经安装了npm和会用npm install等指令,就不详细讲了.下面讲用到grunt-contrib-watch和grunt-contrib-con