当前位置: 首页 > article >正文

解决Vscode中使用netdb.h的getaddrinfo和addrinfo会报错的方法

原文地址:https://kashima19960.github.io/2024/12/03/解决Vscode中使用netdb.h的getaddrinfo和addrinfo会报错的方法/,一般有最新的修改都是在我的个人博客里面,所以在当前平台的更新会比较慢,请见谅😃

前言

博主最近在学习c语言的socket编程,在调用netdb.h中的相关函数和变量api时,遇到了一些问题,因此本文将给出解决的方法,并且进行分析

博主的配置

  • wsl:ubuntu20.04发行版
  • vscode:1.95.3

问题的描述

使用addrinfo(属于netdb.h头文件)结构体变量的时候,vscode会报错

在这里插入图片描述

调用getaddrinfo()函数的时候,vscode也索引不到这个函数的定义
在这里插入图片描述

其实这个函数就位于netdb.h中,可以看到,这一部分是灰色的

在这里插入图片描述

但是使用gcc编译的时候,是能够正确编译链接的,说明程序是没有语法和语义错误的

在这里插入图片描述

因此我推测是vscode的c语言扩展的intellisense智能提示的问题,就是下图的这个扩展(不得不说微软的东西,屁事就是多😅)

在这里插入图片描述

解决的方法

我查阅了很多资料,最终也是找到了解决的方法。我的风格就是先告诉你怎么做,解决你的燃眉之急,至于为什么要这么做,之后我再娓娓道来😋所以如果你对原因分析不感兴趣的话,后面的分析和总结你可以跳过不看❤️

方法1:在插件设置中更改c standard

进入c/c++插件的设置中,找到这一栏
在这里插入图片描述

然后将c99修改成gnu的c语言标准,我试过了,修改成GNU的任意一个都行
在这里插入图片描述

可以看到已经不会报错了
在这里插入图片描述

方法2:定义_GNU_SOURCE

在代码文件中添加_GNU_SOURCE的宏定义

#define _GNU_SOURCE

或者在.vscode中新建一个c_cpp_properties.json,然后在这个文件中定义这个宏,我个人推荐这个做法,因为修改配置文件能作用于整个工程,上面那种只能作用于单个文件。

{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**"
            ],
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "${default}",
            "intelliSenseMode": "${default}",
            "defines": [
                "_GNU_SOURCE"
            ]
        }
    ],
    "version": 4
}

分析与总结

现在来分析一下为什么会报错,造成报错的原因是什么。然后总结一下

原因分析

先说结论:netdb.h属于GNU 特有扩展

标准的c语言本身并不直接包含对netdb.h的支持,所以你现在明白为啥上面打开netdb.h文件后发现有一部分是灰色(说明没有被包含)了吧。

那么GNU的c标准,和普通的c标准有啥区别呢?简单来说就是在普通的c标准上加了很多扩展功能,netdb.h就是GNU特有扩展功能的一部分,所以解决方案2就是这么来的,将c standard切换成GNU C就行了

特性C99GNU99
标准遵循 ISO C99 标准C99 加上 GNU 扩展
扩展不支持 GNU 特有扩展支持 GNU 特有扩展
兼容性严格遵循标准允许使用非标准的 GNU 特性
默认设置不定义 __STRICT_ANSI__定义__STRICT_ANSI__ 以禁用所有 GNU 扩展
  • C99: 这是 1999 年发布的 C 语言标准(ISO/IEC 9899:1999)。它引入了许多新特性,如布尔类型、复合字面量、可变参数宏等。使用 c99 编译器选项时,代码将遵循这一标准。
  • GNU99: 这是基于 C99 标准的 GNU 扩展版本。使用 gnu99 选项时,除了 C99 的特性外,还可以使用 GNU 编译器(GCC)提供的一些额外功能和扩展。这些扩展可能包括额外的语法和库函数,这些在标准 C 中并不被支持。

那么_GNU_SOURCE这个宏又是哪来的?干嘛的?

_GNU_SOURCE是一个宏定义,用于启用GNU C库(glibc)中的许多非标准扩展和功能。定义这个宏后,程序可以访问一些POSIX标准中未包含的传统功能以及GNU/Linux特有的扩展接口。

所以当你定义了这个宏的时候,那么下面标准的所有功能都会启用:ISO C89、ISO C99、POSIX.1、POSIX.2、BSD、SVID、X/Open、LFS 以及 GNU 扩展。在 POSIX.1 与 BSD 发生冲突的情况下,POSIX 定义优先。

这就是解决方案1的由来,定义了这个宏之后就能启用GNU的扩展

总结

有一种说法是写程序都是三分在写,七分在调,我觉得说的很对,写程序最重要的反而不是编写代码,而是如何去调试代码,解决报错,总结问题,我在解决本文的问题的时候,上网查阅了很多资料,以前我并不会去在意C语言不同标准带来的差异,因为写的程序能跑就行😋。但是当你解决问题的时候会发现,你可能会接触到别人写的资料中不胜其烦的枯燥术语,难以理解的代码逻辑,当你经历这个过程后,你的code能力就提升了。

参考资料

  • C99 和 GNU99 的区别 - Undefined443 - 博客园
  • c - What does “#define _GNU_SOURCE” imply? - Stack Overflow
  • 关于__GNU_SOURCE 这个宏 - 颠覆者 - 博客园
  • Incomplete type error on struct addrinfo · Issue #2025 · microsoft/vscode-cpptools

http://www.kler.cn/a/487617.html

相关文章:

  • Angular生命周期
  • WebSocket监听接口
  • Python中的可变对象与不可变对象;Python中的六大标准数据类型哪些属于可变对象,哪些属于不可变对象
  • Android 来电白名单 只允许联系人呼入电话
  • 【Python】基于blind-watermark库添加图片盲水印
  • 免费一键图片转3D模型,AI建模,一键把图片转三维模型,二维图片转3维模型,AI建模
  • 【HTML+CSS+JS+VUE】web前端教程-9-列表标签之有序列表
  • Seed-TTS: A Family of High-Quality Versatile Speech Generation Models
  • ChatGPT网络错误如何解决
  • Leetcode 931. 下降路径最小和 动态规划
  • Windows安装ES单机版设置密码
  • golang 的 panic
  • Vue.js Ajax(vue-resource)
  • XML通过HTTP POST 请求发送到指定的 API 地址,进行数据回传
  • 【算法】一阶低通滤波
  • 单向循环链表的约瑟夫环问题
  • Vue 3 和 Electron 来构建一个桌面端应用
  • STM32 : 奈奎斯特-香农采样定理
  • JavaScript语言的学习路线
  • ChatGPT入门之文本情绪识别:先了解LSTM如何处理文字序列
  • c#集成itext7导出pdf,包含表格
  • 基于SpringBoot的中国陕西民俗网的设计与实现(源码+SQL脚本+LW+部署讲解等)
  • 阅读笔记——《A survey of protocol fuzzing》
  • RabbitMQ解决消息积压的方法
  • SpringCloud Feign 全局Fallback的另一种实现方式(SpringBoot3.4+)
  • iPad编程新体验:如何用IDE Code App实现远程在线开发告别电脑束缚