【问题标题】:C6001 on using the address of uninitialized value. Why?C6001 关于使用未初始化值的地址。为什么?
【发布时间】:2020-11-26 14:14:58
【问题描述】:

这是我的 C++ 代码:

void somefn(char* string){
    char *current, *next;
    current = strtok_s(string, "a", &next);  // next is unitialized -> C6001 in VS 2020
}

int main(){
    char buf[] = "foobar";
    return 0;
}

某些带有某些标志的编译器认为这是值得警告的(我相信这不重要)。

唯一的问题是:

  1. 这会导致未定义的行为吗?我目前认为未初始化变量的地址是编译时常量。
  2. 这会因为某种原因被认为是不好的做法吗?为什么?

编辑:承诺的截图

【问题讨论】:

标签: c++ c initialization compiler-warnings


【解决方案1】:

reference documentation for strtok_s 表明上述代码完全有效假设string 不是空指针。 “未初始化变量的地址是否是编译时常量”完全无关紧要,与诊断无关。编译器认为您正在使用未初始化的内存。

但是,根据文档,strtok_s 的第 4 个参数只有在第一个参数是 NULL 时才需要初始化指向的指针(通过对 strtok_s 的早期调用)。

编译器似乎相当挑剔。看起来编译器无法向自己证明string 在这里永远不会是NULL,所以它在抱怨这个。

但是,如果您从不在这里调用 strtok_s 并在此处使用 NULL 指针,那么这没有任何问题。

【讨论】:

  • 未初始化值警告与string无关,而是与next有关。编译器根本不关心string,它抱怨我使用next(实际上是next的地址)而没有初始化它。
  • 那是绝对正确的,这正是我写的。但是您错过了更大的图景:strtok_s 仅在 stringNULL 时才使用 next,但编译器似乎不知道这一点,并且它认为始终使用 next,正如我解释的那样.
  • @CaptainTrojan:“编译器根本不关心string”:那是错误的。编译器关心string 可能是一个空指针,这将导致next 被未初始化使用。
  • @EricPostpischil next 究竟是如何使用单元化的? next 在我看来从未使用过。如果string == NULL,那么strtok_s 认为这是一个后续调用,恕我直言,应该处理其当前令牌(不是next)并通过引用传递的参数为next 分配一些东西。 (类似于*restrict_ptr = this_and_that,但它不应该使用*restrict_ptr 本身)。
  • @CaptainTrojan:所以,这里的编译器在“思考”:它不知道string 是否为空。而且,如果string 为空,则必须初始化next。由于它没有被初始化,编译器会警告你这种可能性。这是一个过于激进的警告;没有人说这是编译器的良好行为。但这就是它的解释。
猜你喜欢
  • 2021-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多