繁体   English   中英

C-检查是否分配了整数

[英]C - Check if Integer is assigned

如何确定是否未分配整数?

int i; /* no assignment */

if (/* conditional statement here to check if int i is unassigned or not */) {
   printf("Integer is unassigned!\n");
} else {
   printf("Integer is assigned!\n");
}

你不能 它将具有“未定义”的内容,这意味着它将包含当时该内存位置中的所有内容。

除非在全局范围内声明了i,否则它将被初始化为零。

C本质上不支持此功能-就像它本质上不支持对数组进行边界检查一样。 在速度/效率和安全性之间进行权衡。

通常...初始化变量。

非常简单 您知道它尚未分配,因为您没有初始化它。

如果i是全局或静态的,则其值将为0 ,否则它的值可以为任何值,并且无法找出是否为垃圾。

如果使用未初始化的值,您也许可以要求编译器警告。 但是,它们并不是完全可靠的-在DFA不如您希望的那样聪明的情况下,您偶尔会收到误报,并且可能会偶尔出现误报(我希望不会,但我不承担任何责任)。

对于GCC:

-Wuninitialized -O1

如果要编写条件代码:

int a = 3;
int b;
int *p = (rand() > RAND_MAX/2) ? &a : &b;
if (is_uninitialized(*p)) // blah

那你就不走运了 与某些动态语言不同,C没有“未定义的值”的概念。 如果未初始化变量,则不会为它提供一些特殊的值,以便以后进行测试。 它根本没有赋值,因此使用该变量时会发生什么是不确定的。

正如其他人指出的那样,您不能编写一个C程序来检测其自己的变量之一是否未初始化,而应努力确保始终对变量进行初始化。

  • 如果您的目标是确保所有变量都已初始化,则类似valgrind的工具可以通过昂贵的运行时分析来动态检测未初始化变量的使用。

  • 如果您的目标是确保私有数据仅被初始化一次,通常的方法是使用

     int i; static bool initialized = 0; ... if (!initialized) { initialized = 1; i = ... i's initial value ...; } 

通常,C库会将变量设置为0,但这不是必须的。

但基本上,您不能。 在定义中为其分配一个默认值,例如:

int i = 0; /* Or what ever value you know won't be used elsewhere */

然后,如果您运行一些代码并想要检查该值是否在此处设置,则可以与您的初始值进行比较。

正如所有先前的答案一样,没有办法在运行时检测到它。 但是,几乎所有带有静态代码分析工具的工具都会警告您未分配的变量。

在初始化(或分配)之前使用变量是导致错误的严重原因。 您无法在运行时可靠地对其进行检查,但是可以在编译期间或编译之前对其进行检测。

我建议不要在代码中检查它。 因为这可能会引起编译器警告(在给变量赋值之前使用变量“ i”),所以会引入新的错误,并且在大中型程序中成功的可能性很小。

最好的方法是使用静态代码分析工具(例如QA / C或PCLint)。 在高警告敏感度级别使用编译器是一个免费选项,与专用工具相比,其覆盖范围要小得多。

如果执行代码审查,则还可以在清单上包括对未初始化变量的检查。 这不是保证,但会触发审阅者的手动检查。

如果要进行运行时检查,则可以通过将变量初始化为超出范围的值来开始。 例如-1,表示正值。 然后您可以检查

#define UNASSIGNED_VALUE -1
    static int number_of_apples = UNASSIGNED_VALUE;
    if (UNASSIGNED_VALUE == number_of_apples)
    {
       // error handling
    }

这不是真正的“非初始化”变量,但是至少您可以检测到是否在合法范围内完成了运行时分配。

在C语言中,整数在创建时采用未定义的值。 这意味着,如果您第一次使用该整数来自其中具有5893872的寄存器/内存位置/设备,则该整数就是该整数的值。 (调试/发布编译的里程会有所不同。)

解决此问题的常用方法是使用无意义的默认值:

int number_of_widgets = -1;

...或用于指示其状态的标志:

int number_of_widgets;
int number_of_widgets_assigned = 0;

if (number_of_widgets_assigned)
  do something
else
  do something else
number_of_widgets_assigned = 1;

没有其他方法可以检测是否已分配了某些内容-除非您想了解硬件的调试功能,而且我怀疑这与本次对话无关。

对于C而言,检查所使用的变量是否在运行时进行初始化(赋值)是非常困难的。对于C语言来说,它没有语言支持,并且在运行时可用的信息不足以完美检测未初始化的值。 动态分析工具(如Valgrind / Memcheck)经过很长的时间(例如跟踪进程地址空间中的每个内存字节,然后检查每个存储以将字节标记为initiialized),以确定use的值是否已初始化和仍然容易出现误报。

如果您只是想最大程度地减少程序中的此类错误,则诸如lint之类的静态分析工具可以很好地通知您是否正在使用未初始化的变量。 实际上,我相信大多数编译器会尽力告诉您何时进行此操作(尽管它们当然并不完美)。

在C#中,我将使用:

Nullable<int> i = null; /* null assignment */

if (i == null) {
   printf("Integer is unassigned!\n");
} else {
   printf("Integer is assigned!\n");
}

不过,不确定是否将其转换为C。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM