奇怪,C or C++ Compiler为何Build不过这句语句???

yuucyf 2009-08-22 10:03:17
语句:
#if (1, 2) != 2
#else
#endif

为什么,一直不清楚为何Build不过???
理由是什么???
难道预编译指令不Support逗号表达式吗?
...全文
149 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
yuucyf 2009-08-22
  • 打赏
  • 举报
回复
if ((1, 2) != 2)
{
var++;
}

var = (1, 2) != 2;
while ((1, 2) != 2)
{
}
...都可以通过编译
yuucyf 2009-08-22
  • 打赏
  • 举报
回复
(1,2)!=2 是一个表达式吗?

是表达式呀。

if((1,2)!=2)
{
}
可以编译通过。...都可以编译通过,只是在预编译中不能通过编译.
雪影 2009-08-22
  • 打赏
  • 举报
回复
楼主为什么会认为#if (1, 2) != 2 能编译通过呢?
一般#if后边是一个宏或一个表达式。

(1,2)!=2 是一个表达式吗?
MoXiaoRab 2009-08-22
  • 打赏
  • 举报
回复
(1, 2) != 2 这是啥意思?()是个什么运算符呢?
Jinhao 2009-08-22
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 yuucyf 的回复:]
“#if (2)!=2 这个一样会报错,因为内部含有函数,不是常量表达式。”
这个不会报错哦!
[/Quote]

这个当然不会出错

(2) != 2

明显是个常量表达式, 括号只是改变运算优先级。而lz的问题是(1, 2) 这个不是常量表达式,因而
(1, 2) != 2 这整个表达式也不是常量表达式。
MoXiaoRab 2009-08-22
  • 打赏
  • 举报
回复
原来lz是学术型的
yuucyf 2009-08-22
  • 打赏
  • 举报
回复
我在完成一个类似C Language的Script language,目前QA测试过程中遇到这个问题,事实上大多数User不会这么用,因此也不是非常重要,只不过想知道是什么原因?现在在看标准C中,看看能不能找到答案。
ziplj 2009-08-22
  • 打赏
  • 举报
回复
同问
写代码 不是写的让别人看不懂才好
而是写出让一个没学过编程的人都看的了的代码才是好程序员
这种问题 费劲

怀疑楼主是"叫兽" 尽想些外点子整学生
MoXiaoRab 2009-08-22
  • 打赏
  • 举报
回复
LZ,你研究这个有意思吗?
雪影 2009-08-22
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 yuucyf 的回复:]
“#if (2)!=2 这个一样会报错,因为内部含有函数,不是常量表达式。”
这个不会报错哦!
[/Quote]
确实不会,之前没测试过,不好意思。
估计是如果括号内部只有一个表达式的时候会忽略括号吧。
应该是只有当括号里的表达式超过两个才会被认为无名函数吧。
yuucyf 2009-08-22
  • 打赏
  • 举报
回复

“#if (2)!=2 这个一样会报错,因为内部含有函数,不是常量表达式。”
这个不会报错哦!
coderun 2009-08-22
  • 打赏
  • 举报
回复
呵呵,编译不通才是硬道理
Jinhao 2009-08-22
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 tttyd 的回复:]
而#if后面必须是一个常量表达式。
而(1,2)!=2这个不是一个常量表达式
[/Quote]

关键是(1, 2) 不是常量表达式,因此整个也就不是常量表达式了
Jinhao 2009-08-22
  • 打赏
  • 举报
回复
编译不过才正确。

表达式(1, 2) 并不是常量表达式。

#if 后面必须跟的是一个常量表达式。

虽然(1, 2) 里面都是常量,但是这种逗号操作符运算的表达式,C++并不把它看作常量表达式。

判断是不是常量表达式 很简单。case 语句后面必须接一个常量表达式
int i = 2;
switch(i)
{
case (1, 2): //语法错误
break;
}
----
比如,一个整型的常量,如果被常量表达式初始化,那这个常量也是常量表达式
const int a = 0; //文字常量是常量表达式,因此a就是常量表达式,这样a就可以当作编译期常量
const int b = (1, 2); //b并不是常量表达式,不能当作编译期常量
----

回到#if (1, 2) != 2的问题。
这个预编译指令在 GCC 3.4.2能编译通过。所以有些编译器在某些方面对C++语言做了一点扩展。
雪影 2009-08-22
  • 打赏
  • 举报
回复
“()”括号里面如果有多个表达式的话,他将被认为是一个函数,一个无名函数,返回值是最后一个表达式
coderun 2009-08-22
  • 打赏
  • 举报
回复
问题比较生僻
  • 打赏
  • 举报
回复
楼上说的很有意思!
雪影 2009-08-22
  • 打赏
  • 举报
回复
你这个问题很有意思
“()”括号里面如果有多个表达式的话,他将被认为是一个函数,一个无名函数,返回值是最好一个表达式
“()”括号内部如果只有一个表达式,他也是一个无名函数,返回值就是这个表达式


而#if后面必须是一个常量表达式
而(1,2)!=2这个不是一个常量表达式,可以认为他是一个无名函数的表达式。无名函数为“()”。
#if (2)!=2 这个一样会报错,因为内部含有函数,不是常量表达式。
#if 2!=2 这将不报错,因为这是一个常量表达式

这个无名函数的功能是返回括号内部“()”的最后一个表达式。
例: (1,2)返回值是2。 (1,2) !=2 相当于 2 !=2.
再说一个例子。
c++中表达式, (1,2,3,4,5.0)返回值是多少? 返回值是 5.0

你可以将“()”看成一个函数,无名函数,返回值为最后一个表达式
周成风 2009-08-22
  • 打赏
  • 举报
回复
为什么还真不清楚。 。但有点我想说,楼主你钻研这东西麻子用?
初识Visual Leak Detector   灵活自由是C/C++语言的一大特色,而这也为C/C++程序员出了一个难题。当程序越来越复杂时,内存的管理也会变得越加复杂,稍有不慎就会出现内存问题。内存泄漏是最常见的内存问题之一。内存泄漏如果不是很严重,在短时间内对程序不会有太大的影响,这也使得内存泄漏问题有很强的隐蔽性,不容易被发现。然而不管内存泄漏多么轻微,当程序长时间运行时,其破坏力是惊人的,从性能下降到内存耗尽,甚至会影响到其他程序的正常运行。另外内存问题的一个共同特点是,内存问题本身并不会有很明显的现象,当有异常现象出现时已时过境迁,其现场已非出现问题时的现场了,这给调试内存问题带来了很大的难度。   Visual Leak Detector是一款用于Visual C++的免费的内存泄露检测工具。相比较其它的内存泄露检测工具,它在检测到内存泄漏的同时,还具有如下特点:   1、 可以得到内存泄漏点的调用堆栈,如果可以的话,还可以得到其所在文件及行号;   2、 可以得到泄露内存的完整数据;   3、 可以设置内存泄露报告的级别;   4、 它是一个已经打包的lib,使用时无须编译它的源代码。而对于使用者自己的代码,也只需要做很小的改动;   5、 他的源代码使用GNU许可发布,并有详尽的文档及注释。对于想深入了解堆内存管理的读者,是一个不错的选择。   可见,从使用角度来讲,Visual Leak Detector简单易用,对于使用者自己的代码,唯一的修改是#include Visual Leak Detector的头文件后正常运行自己的程序,就可以发现内存问题。从研究的角度来讲,如果深入Visual Leak Detector源代码,可以学习到堆内存分配与释放的原理、内存泄漏检测的原理及内存操作的常用技巧等。   本文首先将介绍Visual Leak Detector的使用方法与步骤,然后再和读者一起初步的研究Visual Leak Detector的源代码,去了解Visual Leak Detector的工作原理。   使用Visual Leak Detector(1.0)   下面让我们来介绍如何使用这个小巧的工具。   首先从网站上下载zip包,解压之后得到vld.h, vldapi.h, vld.lib, vldmt.lib, vldmtdll.lib, dbghelp.dll等文件。将.h文件拷贝到Visual C++的默认include目录下,将.lib文件拷贝到Visual C++的默认lib目录下,便安装完成了。因为版本问题,如果使用windows 2000或者以前的版本,需要将dbghelp.dll拷贝到你的程序的运行目录下,或其他可以引用到的目录。   接下来需要将其加入到自己的代码中。方法很简单,只要在包含入口函数的.cpp文件中包含vld.h就可以。如果这个cpp文件包含了stdafx.h,则将包含vld.h的语句放在stdafx.h的包含语句之后,否则放在最前面。如下是一个示例程序:   #include   void main()   {   …   }   接下来让我们来演示如何使用Visual Leak Detector检测内存泄漏。下面是一个简单的程序,用new分配了一个int大小的堆内存,并没有释放。其申请的内存地址用printf输出到屏幕上。   #include   #include   #include   void f()   {   int *p = new int(0x12345678);   printf("p=%08x, ", p);   }   void main()   {   f();   }   编译运行后,在标准输出窗口得到:   p=003a89c0   在Visual C++的Output窗口得到:   WARNING: Visual Leak Detector detected memory leaks!   ---------- Block 57 at 0x003A89C0: 4 bytes ---------- --57号块0x003A89C0地址泄漏了4个字节   Call Stack: --下面是调用堆栈   d:\test\testvldconsole\testvldconsole\main.cpp (7): f --表示在main.cpp第7行的f()函数   d:\test\testvldconsole\testvldconsole\main.cpp (14): main –双击以引导至对应代码处   f:\rtm\vctools\crt_bld\self_x8

16,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧