microsoft / microsoft/vscode-cpptools

Issue with __VA_OPT__() keyword not expanding properly in a variadic macro

Open
#8,348 5 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug investigate: repro Language Service
Dominant language
TypeScript
Stars
6.2k
Forks
1.7k
Avg merge
14h 46m
Merged PRs (30d)
61

Description

Bug type: Language Service

Describe the bug

  • OS and Version: Linux Ubuntu 20.04
  • VS Code Version: 1.60.2
  • C/C++ Extension Version: v1.7.1
  • Other extensions you installed (and if the issue persists after disabling them): Python, Pylance, PlatformIO, Shader language support for VS Code, Todo+, Jupyter (after disabling all, the problem still persists).
  • If using SSH remote, specify OS of remote machine:
  • A clear and concise description of what the bug is, including information about the workspace (i.e. is the workspace a single project or multiple projects, size of the project, etc).
    I was trying to program a C++ variadic macro that would print an error message to stderr like this:
#define __pError(message, ...) \
{\
    fprintf(stderr, "\x1B[31mERROR: Error at file %s, line %d:\x1B[0m ",\
            __FILE__, __LINE__);\
    fprintf(stderr, message __VA_OPT__(,) __VA_ARGS__);\
    fprintf(stderr, "\n");\
    exit(-1);\
}

I then used the macro like this:

__pError("I am going to produce an error!");

Now, this should work, but instead I get an error message:
" expected a ')' "
When I compile my project using g++, I don't get errored out; it compiles just fine.
I think the problem is with the VA_OPT() keyword; maybe it isn't implemented?

Steps to reproduce

  1. Make a file, let's call it file.h
  2. Paste the macro definition code into said file.
  3. At the top, put #pragma once, #include <stdio.h> and #include <stdlib.h>.
  4. Make another file, let's call it main.cpp.
  5. Insert #include <file.h> at the top
  6. Update includePath in VSCode cpp configuration files to include file.h.
  7. Put in a main function:
int main()
{
    __pError("Why am I recieving an error?");

    return 0;
}
  1. See error

Expected behavior

There should be no error; no red squiggly lines.

Code sample and logs

  • Code sample
    file.h:
#pragma once

#define __pError(message, ...) \
{\
    fprintf(stderr, "\x1B[31mERROR: Error at file %s, line %d:\x1B[0m ",\
            __FILE__, __LINE__);\
    fprintf(stderr, message __VA_OPT__(,) __VA_ARGS__);\
    fprintf(stderr, "\n");\
    exit(-1);\
}

main.cpp:

#include "file.h"

int main()
{
    __pError("Why am I recieving an error?");

    return 0;
}
  • Configurations in c_cpp_properties.json
{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/include"
            ],
            "defines": ["GL_GLEXT_PROTOTYPES"],
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "gnu17",
            "cppStandard": "gnu++14",
            "intelliSenseMode": "linux-gcc-x64"
        }
    ],
    "version": 4
}
  • Logs from running C/C++: Log Diagnostics from the VS Code command palette
-------- Diagnostics - 10/30/2021, 6:54:58 PM
Version: 1.7.1
Current Configuration:
{
    "name": "Linux",
    "includePath": [
        "${workspaceFolder}/include"
    ],
    "defines": [
        "GL_GLEXT_PROTOTYPES"
    ],
    "compilerPath": "/usr/bin/gcc",
    "cStandard": "gnu17",
    "cppStandard": "gnu++14",
    "intelliSenseMode": "linux-gcc-x64",
    "compilerPathIsExplicit": true,
    "cStandardIsExplicit": true,
    "cppStandardIsExplicit": true,
    "intelliSenseModeIsExplicit": true,
    "compilerArgs": [],
    "mergeConfigurations": false,
    "browse": {
        "path": [
            "${workspaceFolder}/include",
            "${workspaceFolder}"
        ],
        "limitSymbolsToIncludedHeaders": true
    }
}
Translation Unit Mappings:
[ /home/ben/c/game/src/test.cpp ]:
    /home/ben/c/game/src/test.cpp
    /home/ben/c/game/include/Utils.h
Translation Unit Configurations:
[ /home/ben/c/game/src/test.cpp ]:
    Process ID: 40704
    Memory Usage: 14 MB
    Compiler Path: /usr/bin/gcc
    Includes:
        /home/ben/c/game/include
        /usr/include/c++/9
        /usr/include/x86_64-linux-gnu/c++/9
        /usr/include/c++/9/backward
        /usr/lib/gcc/x86_64-linux-gnu/9/include
        /usr/local/include
        /usr/include/x86_64-linux-gnu
        /usr/include
    Defines:
        GL_GLEXT_PROTOTYPES
    Standard Version: c++14
    IntelliSense Mode: linux-gcc-x64
    Other Flags:
        --g++
        --gnu_version=90300
Total Memory Usage: 14 MB

------- Workspace parsing diagnostics -------
Number of files discovered (not excluded): 5969

Screenshots

None should be needed, but some can be provided if necessary.

Additional context

If more context is needed, I can provide, but I don't think any more is necessary.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the macro diagnostic from file.h and main.cpp with the supplied c_cpp_properties.json, then compare the configured C++ standard with the compiler behavior. Trace how the language service parses VA_OPT in this variadic macro. Done means the supplied example is accepted without the reported closing-parenthesis error while preserving the existing diagnostics behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.