越界访问和UB [英] Out-of-bounds access and UB

查看:82
本文介绍了越界访问和UB的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,


有人将以下代码发布到其他组:


void function2(int a,int b,int c ){

int exchange;

char buffer [3];

char * bufPt;

buffer [0 ] =''A'';

缓冲区[3] =''B'';

缓冲区[40] ='''B'';

bufPt =缓冲区;

bufPt = bufPt + 1;

}


注意:缓冲区[3]和缓冲区[40]超出界限。


我回答:[...]我相信''function2''有不确定的行为。

换句话说,编译器可以自由地做任何想做的事情[...]


然后有人评论说:没有。从技术上讲,该计划完全符合
。它正在执行给出未定义行为的程序。


什么是技术上程序完全符合是什么意思?

我的措辞不正确吗?


也许源代码不能有未定义的行为,只有可执行的

代码可以吗?我有点困惑。你可以请点亮一下吗?


-

问候,Nudge

解决方案

Nudge写道:


你好,

有人将以下代码发布到另一组:

void function2(int a,int b,int c){
int exchange;
char buffer [3];
char * bufPt;
buffer [0] =''A '';
缓冲区[3] ='''B'';
缓冲区[40] ='''B'';
bufPt =缓冲区;
bufPt = bufPt + 1 ;
}

注意:缓冲区[3]和缓冲区[40]超出范围。

我回答:[...]我相信''function2''具有未定义的行为。


确实如此。

换句话说,编译器可以自由地做任何想做的事情[...]"


有一些限制。见N869,3.18,[#2]

然后有人评论说:不。从技术上讲,该计划完全符合要求。


不是。

执行程序会产生未定义的行为。

什么是从技术上讲,该计划完全符合意思是?
我的措辞不正确吗?

也许源代码不能有未定义的行为,只有可执行的代码可以吗?我有点困惑。你能否解释一下?




C程序包含未定义的行为。

源代码是C程序。

C的规则,不需要编译器检测到这种特定类型的

未定义的行为,

因此不需要生成警告编译器。


N869

3.18

[#1]未定义行为

行为,在使用不可移植或错误的程序

构造,错误数据或不确定的价值

物品,本国际标准没有规定

要求

[#2]注意可能的未定义行为包括忽略完全具有不可预测结果的情况,以及

在翻译或程序执行期间的行为以

记录的环境特征(带有或者

而没有发行诊断消息),

终止翻译或执行(发出

a诊断信息)。


-

pete




" Nudge" <豪****** @ kma.eu.org>写了


void function2(int a,int b,int c){
int exchange;
char buffer [3];
char * bufPt ;
缓冲区[0] =''A'';
缓冲区[3] =''B'';
缓冲区[40] ='''B'';
bufPt =缓冲区;
bufPt = bufPt + 1;
}
注意:缓冲区[3]和缓冲区[40]超出范围。

我回答:[...]我相信''function2''具有未定义的行为。
换句话说,编译器可以自由地做任何想做的事情[...]"

然后有人评论道:不。从技术上讲,该计划完全符合要求。它正在执行给出未定义行为的程序。

什么是技术上程序完全符合意思是?
我的措辞不正确吗?

也许源代码不能有未定义的行为,只有可执行的代码可以吗?我有点困惑。请问你能解决一些问题吗?



很多编译器都非常愚蠢,而且只会覆盖与原来地址相对应的内存

位置,如果数组

足够大,给出的值。毋庸置疑,这样做的结果是不可预测的。如果内存不用于其他任何内容,

程序可以正确工作,如果你覆盖函数返回

地址你将会崩溃,如果你腐败的数据你会得到错误

结果在程序的其他地方。


标准只是试图形式化这一点,通过说行为是

" undefined" ;.

聪明的编译器会检测越界访问,并发出

警告。我不知道是否允许拒绝该程序,

或者是否必须编译它以执行非法操作。除非你实际上是在实现一个编译器,否则它并不是很重要。


源代码无法运行,因此无法显示任何行为,定义或

否则。编译器可以生成执行

标准所述的任何可执行代码,因此如果提供包含未定义行为的程序,那么从技术上讲它可以产生任何输出。在实践中,它会盲目地丢弃内存,或者在受保护的环境中以

终止错误消息。


< blockquote> Nudge写道:

你好,

有人将以下代码发布到另一组:

void function2(int a ,int b,int c){
int exchange;
char buffer [3];
char * bufPt;
buffer [0] =''A'';
buffer [3] =''B'';
缓冲区[40] =''B'';
bufPt =缓冲区;
bufPt = bufPt + 1;
}




使用lcc-win32编译器得到:

D:\lcc\mc59 \ test> lcc -c tub .c

警告tub.c:6索引数组缓冲区[3]超出界限(3)

警告tub.c:7索引数组缓冲区[40]界限(3)

0错误,2次警告


Hello,

Someone posted the following code to a different group:

void function2(int a, int b, int c) {
int exchange;
char buffer[3];
char *bufPt;
buffer[0] = ''A'';
buffer[3] = ''B'';
buffer[40] = ''B'';
bufPt = buffer;
bufPt = bufPt + 1;
}

Note: buffer[3] and buffer[40] are out-of-bounds.

I answered: "[...] I believe ''function2'' has undefined behavior.
In other words, the compiler is free to do anything it wants [...]"

Then someone commented: "No. Technically the program is fully
conforming. It is executing the program that gives undefined behaviour."

What does "Technically the program is fully conforming" mean?
Was my wording incorrect?

Perhaps source code cannot have undefined behavior, only executable
code can? I am somewhat confused. Could you please shed some light?

--
Regards, Nudge

解决方案

Nudge wrote:


Hello,

Someone posted the following code to a different group:

void function2(int a, int b, int c) {
int exchange;
char buffer[3];
char *bufPt;
buffer[0] = ''A'';
buffer[3] = ''B'';
buffer[40] = ''B'';
bufPt = buffer;
bufPt = bufPt + 1;
}

Note: buffer[3] and buffer[40] are out-of-bounds.

I answered: "[...] I believe ''function2'' has undefined behavior.
It does.
In other words, the compiler is free to do anything it wants [...]"
There are some limitations. See N869, 3.18, [#2]
Then someone commented: "No. Technically the program is fully
conforming.
It isn''t.
It is executing the program that gives undefined behaviour."

What does "Technically the program is fully conforming" mean?
Was my wording incorrect?

Perhaps source code cannot have undefined behavior, only executable
code can? I am somewhat confused. Could you please shed some light?



The C program contains undefined behavior.
The source code is the C program.
The rules of C, do not require this particular type of
undefined behavior to be detected by the complier,
so no warnings are required to be generated by the compiler.

N869
3.18
[#1] undefined behavior
behavior, upon use of a nonportable or erroneous program
construct, of erroneous data, or of indeterminately valued
objects, for which this International Standard imposes no
requirements
[#2] NOTE Possible undefined behavior ranges from ignoring
the situation completely with unpredictable results, to
behaving during translation or program execution in a
documented manner characteristic of the environment (with or
without the issuance of a diagnostic message), to
terminating a translation or execution (with the issuance of
a diagnostic message).

--
pete



"Nudge" <ho******@kma.eu.org> wrote


void function2(int a, int b, int c) {
int exchange;
char buffer[3];
char *bufPt;
buffer[0] = ''A'';
buffer[3] = ''B'';
buffer[40] = ''B'';
bufPt = buffer;
bufPt = bufPt + 1;
}

Note: buffer[3] and buffer[40] are out-of-bounds.

I answered: "[...] I believe ''function2'' has undefined behavior.
In other words, the compiler is free to do anything it wants [...]"

Then someone commented: "No. Technically the program is fully
conforming. It is executing the program that gives undefined behaviour."

What does "Technically the program is fully conforming" mean?
Was my wording incorrect?

Perhaps source code cannot have undefined behavior, only executable
code can? I am somewhat confused. Could you please shed some light?


A lot of compilers are pretty stupid, and will simply overwrite the memory
locations that would have corresponded to the right address, had the array
been large enough, with the values given. Needless to say the results of
doing this are unpredictable. If the memory is not used for anything else,
the program may work "correctly", if you overwrite the function return
address you will get a crash, if you corrupt over data you will get wrong
results somewhere else in the program.

The standard just tries to formalise this, by saying that the behaviour is
"undefined".

A clever compiler will detect the out of bounds access, and deliver a
warning. I don''t know offhand whether it is allowed to reject the program,
or if it has to compile it to perform the illegal action. It doesn''t much
matter, unless you are actually implementing a compiler.

Source code cannot be run, so cannot show any kind of behaviour, defined or
otherwise. A compiler can produce any executable code that does what the
standard says, so if fed a program containing undefined behaviour then
technically it could produce any output whatsoever. In practise it would
either blindly trash memory or, in a protected environment, terminate with
an error message.


Nudge wrote:

Hello,

Someone posted the following code to a different group:

void function2(int a, int b, int c) {
int exchange;
char buffer[3];
char *bufPt;
buffer[0] = ''A'';
buffer[3] = ''B'';
buffer[40] = ''B'';
bufPt = buffer;
bufPt = bufPt + 1;
}



Using the lcc-win32 compiler you get:
D:\lcc\mc59\test>lcc -c tub.c
Warning tub.c: 6 indexing array buffer[3] out of bounds (3)
Warning tub.c: 7 indexing array buffer[40] out of bounds (3)
0 errors, 2 warnings


这篇关于越界访问和UB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆