【问题标题】:C/C++ extension for Visual Studio Code, gcc, Mac: "variable uint32_t is not a type name"Visual Studio Code、gcc、Mac 的 C/C++ 扩展:“变量 uint32_t 不是类型名称”
【发布时间】:2017-08-15 20:39:39
【问题描述】:

我已经开始在我的嵌入式 C 项目中使用 VSC,并在 Mac 上使用 gcc for ARM。在c_cpp_properties.json 中设置包含路径后,我的大部分#includes 现在都可以工作了。但是,像这样的一行:

uint32_t m_ttff_seconds = 0;

产生红色波浪下划线和错误:

variable uint32_t is not a type name

有问题的源文件包括stdint:

#include <stdint.h>

includePath 包括:

"${HOME}/dev/gcc-arm-none-eabi-4_9-2015q3/lib/gcc/arm-none-eabi/4.9.3/include"

和:

"intelliSenseMode": "clang-x64"

(唯一的其他选项是msvc-x64)。

当我使用 make 和 gcc 时,代码库编译得很好。如何显示 uint32_t 所在的 C/C++ 扩展?

编辑:

stdint.h 看起来像这样:

#ifndef _GCC_WRAP_STDINT_H
#if __STDC_HOSTED__
# if defined __cplusplus && __cplusplus >= 201103L
#  undef __STDC_LIMIT_MACROS
#  define __STDC_LIMIT_MACROS
#  undef __STDC_CONSTANT_MACROS
#  define __STDC_CONSTANT_MACROS
# endif
# include_next <stdint.h>
#else
# include "stdint-gcc.h"
#endif
#define _GCC_WRAP_STDINT_H
#endif

stdint-gcc.h 包含:

/* 7.8.1.1 Exact-width integer types */

#ifdef __INT8_TYPE__
typedef __INT8_TYPE__ int8_t;
#endif
#ifdef __INT16_TYPE__
typedef __INT16_TYPE__ int16_t;
#endif
#ifdef __INT32_TYPE__
typedef __INT32_TYPE__ int32_t;
#endif
#ifdef __INT64_TYPE__
typedef __INT64_TYPE__ int64_t;
#endif
#ifdef __UINT8_TYPE__
typedef __UINT8_TYPE__ uint8_t;
#endif
#ifdef __UINT16_TYPE__
typedef __UINT16_TYPE__ uint16_t;
#endif
#ifdef __UINT32_TYPE__
typedef __UINT32_TYPE__ uint32_t;
#endif
#ifdef __UINT64_TYPE__
typedef __UINT64_TYPE__ uint64_t;
#endif

这表明 __UINT32_TYPE__ 在 VSC 解析我的代码时没有定义,但它是在我使用 make 和 gcc 构建时定义的。

编辑:

根据@mbmcavoy 的回答,我将我的c_cpp_properties.json 文件包含在此处:

{
    "configurations": [
        {
            "name": "Mac",
            "includePath": [
                "${HOME}/dev/gcc-arm-none-eabi-4_9-2015q3/lib/gcc/arm-none-eabi/4.9.3/include",
                "${HOME}/dev/nRF5_SDK_14.0.0_3bcc1f7/components/libraries/util",
                "${HOME}/dev/nRF5_SDK_14.0.0_3bcc1f7/config",
                [many more of these omitted]
                "${HOME}/dev/wisol_SDK_SFM20Rx_master/development/sigfox_cfg2/source",
                "${workspaceRoot}"
            ],
            "browse": {
                "path": [
                    "${HOME}/dev/gcc-arm-none-eabi-4_9-2015q3/lib/gcc/arm-none-eabi/4.9.3/include",
                    "${HOME}/dev/nRF5_SDK_14.0.0_3bcc1f7/components/libraries/util",
                    "${HOME}/dev/nRF5_SDK_14.0.0_3bcc1f7/config",
                    [many more of these omitted]
                    "${workspaceRoot}"
                ],
                "databaseFilename": "${workspaceRoot}/.vscode/browse.vc.db"
            },
            "intelliSenseMode": "clang-x64",
            "macFrameworkPath": [
                "/System/Library/Frameworks",
                "/Library/Frameworks"
            ],
            "defines": [
                "__UINT_LEAST16_MAX__=65535",
                "__UINT_LEAST8_TYPE__=unsigned char",
                "__UINT8_MAX__=255",
                "__UINT_FAST64_MAX__=18446744073709551615ULL",
                "__UINT_FAST8_MAX__=4294967295U",
                "__UINT_LEAST64_MAX__=18446744073709551615ULL",
                "__UINT_LEAST8_MAX__=255",
                "__UINTMAX_TYPE__=long long unsigned int",
                "__UINT32_MAX__=4294967295UL",
                "__UINT16_C(c)=c",
                "__UINT16_MAX__=65535",
                "__UINT8_TYPE__=unsigned char",
                "__UINT64_C(c)=c ## ULL",
                "__UINT_LEAST16_TYPE__=short unsigned int",
                "__UINT64_MAX__=18446744073709551615ULL",
                "__UINTMAX_C(c)=c ## ULL",
                "__UINT_FAST32_MAX__=4294967295U",
                "__UINT_LEAST64_TYPE__=long long unsigned int",
                "__UINT_FAST16_TYPE__=unsigned int",
                "__UINT_LEAST32_MAX__=4294967295UL",
                "__UINT16_TYPE__=short unsigned int",
                "__UINTPTR_MAX__=4294967295U",
                "__UINT_FAST64_TYPE__=long long unsigned int",
                "__UINT_LEAST32_TYPE__=long unsigned int",
                "__UINT8_C(c)=c",
                "__UINT64_TYPE__=long long unsigned int",
                "__UINT32_C(c)=c ## UL",
                "__UINT_FAST32_TYPE__=unsigned int",
                "__UINTMAX_MAX__=18446744073709551615ULL",
                "__UINT32_TYPE__=long unsigned int",
                "__UINTPTR_TYPE__=unsigned int",
                "__UINT_FAST16_MAX__=4294967295U",
                "__UINT_FAST8_TYPE__=unsigned int"
            ]
        }
    ],
    "version": 3
}

编辑:

在深入挖掘时,我发现gcc-arm-none-eabi-4_9-2015q3/lib/gcc/arm-none-eabi/4.9.3/include/stdint.h 定义了__STDC_HOSTED__,因此stdint-gcc.h 实际上并未包含在内。相反,该标头执行“include_next &lt;stdint.h&gt;”,它会找到gcc-arm-none-eabi-4_9-2015q3/arm-none-eabi/include/stdint.h。我仍然看不到 unint32_t 是在哪里定义的,无论是 gcc 和 make 还是 VSC。

【问题讨论】:

  • 这是 C 还是 C++?另外,您使用的是什么版本的 Visual Studio?
  • C. Visual Studio 代码。
  • 路径中的“.../include”之后是否缺少某些内容?
  • 不,这就是 stdint.h 和 stdint-gcc.h 所在的地方。
  • 不确定发生了什么,但您可以使用 typedef 来解决这个限制

标签: c gcc visual-studio-code


【解决方案1】:

在尝试了所有建议的解决方案均无效后,我认为 uint32_t 问题是一个错误。

要解决 VSCode 中烦人的警告,只需在 #include 部分之后添加以下行:

typedef __uint32_t uint32_t;

通过在单个文件中执行一次,它修复了我的 VSCode 警告并且仍然可以编译。

【讨论】:

    【解决方案2】:

    我已经能够在我的机器 (Windows) 上通过三个步骤解决此问题:

    1. 将编译器定义应用于 C/C++ 扩展

    当它指出“这表明 __UINT32_TYPE__ 在 VSC 解析我的代码时未定义,但在我使用 make 和 gcc 构建时已定义”时,问题是正确的。 ARM 交叉编译器有许多内置定义,这些定义未包含在 clang-x64 解析器中。

    首先,使用-dM -E 选项找出您的gcc 编译器定义。在 Windows 上,我可以使用 echo | arm-none-eabi-gcc -dM -E - &gt; gcc-defines.txt 将输出转储到文件中

    #define __DBL_MIN_EXP__ (-1021)
    #define __HQ_FBIT__ 15
    #define __UINT_LEAST16_MAX__ 0xffff
    #define __ARM_SIZEOF_WCHAR_T 4
    #define __ATOMIC_ACQUIRE 2
    #define __SFRACT_IBIT__ 0
    #define __FLT_MIN__ 1.1754943508222875e-38F
    #define __GCC_IEC_559_COMPLEX 0
    (etc. - I have 344 defines)
    

    其次,将定义添加到您的c_cpp_properties.json 文件中。请注意,在#define 设置值的地方,您需要在此处使用= 符号。 (您可以根据需要添加单独的定义,但我使用 Excel 根据需要对其进行格式化和排序。第一个定义用于我的项目,与我的 Makefile 中的定义匹配。)

    "defines": [
        "STM32F415xx",
        "USE_FULL_LL_DRIVER",
        "__USES_INITFINI__",
        "__ACCUM_EPSILON__=0x1P-15K",
        "__ACCUM_FBIT__=15",
        (...)
        "__UINT32_TYPE__=long unsigned int",
        (etc.)
    
    1. 设置符号数据库

    在对单个定义进行了一些实验之后,我可以看到该定义正在stdint-gcc.h 中处理,任何类型的使用仍然会产生错误。我在我的c_cpp_properties.json 文件中意识到我有"databaseFilename": "" 这用于“生成的符号数据库”,但没有正确配置。我将其设置为:

    "databaseFilename": "${workspaceRoot}/.vscode/browse.vc.db"
    
    1. 重启 Visual Studio Code

    退出并重新启动 Visual Studio Code 后,声明不会导致错误,并且当将鼠标悬停在变量上时,它会显示适当的类型。

    【讨论】:

    • 无论如何都应该定义它。至少从 VS10 开始,C/C++ 编译器 (cl.exe) 就知道 stdint.h 是什么,uint32_t 是什么了。
    • Visual Studio Code 与 Visual Studio 不同,不包括编译器或头文件。如果还安装了 Visual Studio,它可以使用它们,但是在为嵌入式 ARM 处理器开发时,这些是错误的编译器和头文件。对 arm-none-eabi-gcc 的引用是针对 GNU ARM 工具链的。 Visual Studio Code 中的解析器必须告诉在哪里可以找到这些头文件,以及该编译器使用的内置定义。
    • 在问题中,@eliot 更改了包含路径,以便 VSCode 解析器找到正确的 ARM 标头。但是,如果没有至少一些定义,则无法正确处理标头,从而导致 uint32_t 定义不正确。请注意,他也在 Mac 上,没有可用的 Microsoft 编译器,尽管默认情况下,默认指向的等效系统头文件应该位于的位置。
    • @mbmcavoy 感谢您提供了令人敬畏的细节,但我已经非常密切地关注了这一点,并且仍然看到 uint32_t 上的错误。我只使用了定义的一个子集,但我认为我已经涵盖了所有 UNIT 内容。有什么想法吗?
    • @eliot 当我第一次这样做时,我以为我只是手动放入了我需要的那些并且它起作用了,但是我正在回溯我的步骤以进行完整的写作,发现它没有。中间标头(stdint.h x2 等)有许多 #ifdef 指令,所以我认为没有它们甚至无法进入 stdint-gcc.h。追踪每一个并手动输入是可能的,但很容易将它们全部加载:转储到文件;删除前导的“#define”;如果有空格,用等号替换第一个;粘贴到设置中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-05
    • 1970-01-01
    • 1970-01-01
    • 2016-05-18
    • 2021-11-22
    • 1970-01-01
    相关资源
    最近更新 更多