Почему я не получаю предупреждение от своего компилятора, хотя я добавил эти параметры компилятора в tasks.json?

#c #visual-studio-code #g #warnings

#c #visual-studio-code #g #предупреждения

Вопрос:

Я использую VSCode и следовал этому руководству: https://code.visualstudio.com/docs/cpp/config-mingw

В моем tasks.json файле я добавил два аргумента командной строки "-Wall" , "-fsanitize=undefined" и -fsanitize=address .

Теперь файл выглядит так:

 {
    "version": "2.0.0",
    "tasks": [
        {
            "type": "shell",
            "label": "C/C  : g  .exe build active file",
            "command": "C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin\g  .exe",
            "args": [
                "-g",
                "-Wall",
                "-fsanitize=undefined",
                "-fsanitize=address",
                "${file}",
                "-o",
                "${fileDirname}\${fileBasenameNoExtension}.exe"
            ],
            "options": {
                "cwd": "${workspaceFolder}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}
 

Если я запускаю простой фрагмент кода ниже, я не получаю никакого предупреждения, хотя я пытаюсь получить доступ к элементу с индексом 3 вектора размером 1. Что мне нужно сделать, чтобы получить предупреждение / ошибку?

 #include <iostream>
#include <vector>

int main()
{
    std::vector<int> a(1);
    std::cout << a[3];
}
 

Комментарии:

1. Вы всегда можете добавить эту проверку ошибок в свой контрольный список проверки кода.

2. Теперь я вижу, что только самая последняя версия g предупреждает о доступе за пределы. 10.2 не предупреждает, но магистральная версия предупреждает в goldbolt.

3. Я думаю, вам придется обратиться к ответу Натана и использовать at() его для получения исключений. Компилятор может улавливать только простые ошибки, выходящие за рамки, поэтому на это нельзя положиться, даже если вы получите более новую g версию. Просто подумайте, получаете ли вы какой-либо пользовательский ввод, который следует использовать в качестве индекса. Компилятор никогда не сможет это уловить.

4. @Ruirui Если вы отлаживаете, скомпилируйте свою программу (и добавьте -fsanitize=address ) Я почти уверен, что вы получите хороший дамп при выполнении того, что делает программа в вопросе. Я не думаю, что VSCode имеет какое-либо отношение к тому, что происходит. Это afaik редактор.

5.@Ruirui Что g --version сообщает? g 8.1 кажется, это красиво сбрасывается

Ответ №1:

Нет способа гарантировать предупреждение или ошибку при доступе к вектору за пределами границ.

Однако вы можете переключиться с использования [] на использование at like

 int main()
{
    std::vector<int> a(1);
    std::cout << a.at(3);
}
 

который сгенерирует исключение во время выполнения, и вы можете написать код для обработки этого исключения.

Комментарии:

1. нет ли какой-либо возможности гарантировать ошибку выхода за пределы, используя флаги компиляции (при использовании [] )?

2. @Ruirui AFAIK, нет. Это слишком много работы для компилятора. В случаях, когда у вас есть локальный массив, и вы используете значение времени компиляции, компилятор может предупредить, но вектор не имеет известного размера элементов во время компиляции, и поэтому анализировать код намного сложнее. Вот почему at существует или вы всегда ставите проверку на access, чтобы убедиться, что индекс действителен.