компилятор clang говорит: переменная 'ptr' может быть неинициализирована - PullRequest
1 голос
/ 21 февраля 2020

Я скомпилирую следующий код с помощью clang следующим образом:

clang main.cpp -Werror -Wconditional-uninitialized

Код:

    #include <stdio.h>

    bool captureSupported() {
      return true;    // it makes no difference to the compiler if it returns true or false
}

// false - success, true - failure
bool capture(char **ptr) {
  // it makes no difference to the compiler if it is commented out or not
  // *ptr = (char*)"captured";  
  return true;    // it makes no difference to the compiler if it returns true or false
}

void foo() {
  char *ptr;
  bool capture_raw = true;

  if(captureSupported() && (!capture(&ptr)) ) { // compilation warning/error
//  if(true && (!capture(&ptr)) ) {             // no warning/error
//  if(false && (!capture(&ptr)) ) {            // no warning/error
//  if(captureSupported() && (!false) ) {       // no warning/error
//  if(captureSupported() && (!true) ) {        // no warning/error
    capture_raw = false;
  } else {
    printf("cannot capture\n");
  }

 if(capture_raw) {
    ptr = (char*)"raw captured";
  }

  printf("%s", ptr);
}

int main() {
  foo();
  return 0;
}

Может кто-нибудь объяснить мне, почему результат компиляции:

main.cpp:33:16: error: variable 'ptr' may be uninitialized when used here [-Werror,-Wconditional-uninitialized]
  printf("%s", ptr);
               ^~~
main.cpp:16:12: note: initialize the variable 'ptr' to silence this warning
  char *ptr;
           ^
            = nullptr
1 error generated.

Нет никакого возможного пути, где ptr неинициализирован. Или, если компилятор настолько умен, чтобы выяснить, что capture () не мог его инициализировать, зачем комментировать слова «если», которые делают компилятор счастливым?

Ответы [ 2 ]

1 голос
/ 21 февраля 2020

Вы неправильно читаете предупреждение.

переменная 'ptr' может быть неинициализирована при использовании здесь

Это означает, что компилятор может не доказывает, что переменная инициализирована перед использованием, а не то, что может доказать, что она не инициализирована.

0 голосов
/ 21 февраля 2020

Я бы просто сделал то, что предлагает компилятор, и инициализировал бы вашу переменную. Это отключит предупреждение. Это лучшая практика, которая создает более безопасный код.

...