'Visual Studio Code: how to add arguments for g++ compiler?

I want to use some C++17 features that Mac's clang doesn't currently support, so I use

brew install gcc --HEAD

to install the g++ 10.0.1 version. Codes run well in terminal by directly calling

g++-HEAD -std=c++17 test.cpp

I also created a link ln -s g++-HEAD g++ in bash, and added an alias alias g++='g++ -std=c++17' in .bash_profile, so that

g++ test.cpp

will do the same job.

I want to run C++ code in Visual Studio Code - Mac version. After installing its C/C++ Extension by Microsoft, and Code Runner Extension, I set up the settings.json file in VSCode to include compiler argument:

{
    "C_Cpp.default.cppStandard": "c++17",
    "C_Cpp.default.compilerPath": "/usr/bin/g++",
    "C_Cpp.default.intelliSenseMode": "gcc-x64",
    "C_Cpp.default.compilerArgs": [
        "-std=c++17"
    ]
}

Then I tried to run the same code. However, I got warning:

[Running] cd "/some directory/" && g++ test.cpp -o test && "/some directory/"test
warning: fold-expressions only available with '-std=c++17' or '-std=gnu++17'

Clearly, it means the g++ compiler ran in VSCode is not the one I manually set with alias. More interestingly, if I run directly in VSCode TERMINAL, my previous code

g++ test.cpp -o test

works.

I'm confused by the setup in VSCode: why doesn't the runner use the same g++ compiler argument as used in VSCode's own terminal? Also, how should I modify the settings.json file or some other files in VSCode so that I can correctly add the -std=c++17 argument?



Solution 1:[1]

Here is my solution to this predicament. I link it with my projects Makefile.

First, you'll need to build a Makefile, if your using GCC using a Makefile on its own is... controversial to say the least. But I think it serves the purposes of this example. As you may know, running "make" instead of g++ in the current directory will parse the Makefile and run the corresponding commands. But in your case, your Makefile may look similar to:

#You're gonna wanna make it think that your executable doesnt exist, otherwise,
#because the executable exists, make will assume its the most recent build.
.PHONY: debug 


#using g++ and the flags inline like this, is generally seen as bad practice, it might be worth
#looking into using Makefiles to make this more acceptable, but this will get you started.
debug:
    g++ -g -o debug main.cpp -std=c++17

clean:
    rm debug
#if you copy this exactly, make you you replace the spaces with proper tab
#characters otherwise it will error out.

The Juicy part is in VS code; It has a very power feature known as tasks. Tasks are their very own special rabbit hole, but to put it bluntly, you add a task to the "tasks" array in a generated tasks.json file in your workspace, if you're not familar with how that might look, here is the syntax for a task:

    {
        "label": "[name of task]",
        "type": "[type of task, usually its a shell command]",
        "command": "[the actual command to call]"
    }

There are many more features that tasks can offer, but for making a build tool this will be all you need, for me, this resulted in a file that looked like this:

{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
    {
        "label": "build_debug",
        "type": "shell",
        "command": "make"
    },
    {
        "label": "clean",
        "type": "shell",
        "command": "make clean"
    },
    {
        "label": "build",
        "dependsOn": [
            "clean",
            "build_debug"
        ],
        "problemMatcher": [
            "$gcc"
        ]
    }
]
}

Why do we need to have a final build call? because your launch.json object can take a "preLaunchTask" that will automatically call prior to debug. You can slap in that final build call, and it will compile, debugger, and then run your app. it will even integrate GDB breakpoints and memory tracking into the workspace. My launch.json looks like this:

{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
    {
        "name": "(gdb) Launch",
        "type": "cppdbg",
        "request": "launch",
        "program": "${workspaceFolder}/runnable",
        "args": [],
        "stopAtEntry": false,
        "cwd": "${workspaceFolder}",
        "environment": [],
        "externalConsole": false,
        "MIMode": "gdb",
        "preLaunchTask": "build",
        "setupCommands": [
            {
                "description": "Enable pretty-printing for gdb",
                "text": "-enable-pretty-printing",
                "ignoreFailures": false
            }
        ]
    }
]
}

Sorry for the long replay, i hope it helps :)

Solution 2:[2]

Assuming you use the C/C++ extension, create a task.json file, which will allow you to change settings such as the path to the compiler, include paths, C++ standard, optimization (default is C++17), and more.

From the code tutorial:

From the main menu, choose Terminal > Configure Default Build Task. A dropdown appears showing various predefined build tasks for C++ compilers. Choose C/C++: g++ build active file.

This will create a tasks.json file in a .vscode folder and open it in the editor.

Your new tasks.json file should look similar to the JSON below

My file looks like

tasks.json

{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++ build active file",
            "command": "/usr/bin/g++",
            "args": [
                "-std=c++17",
                "-ggdb",
                "-Og",
                "${file}",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}"
            ],
            "options": {
                "cwd": "${workspaceFolder}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "compiler: /usr/bin/g++"
        }
    ]
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Pnelego
Solution 2