news 2026/6/10 8:16:16

语法检查 vs 语义检查——编译器是怎么审你的代码的?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
语法检查 vs 语义检查——编译器是怎么审你的代码的?

目录

语法检查 vs 语义检查——编译器是怎么审你的代码的?

一、一个比喻:老师改作文

二、语法检查:你的话"说对"了吗?

定义

编译器做了什么

典型语法错误

典型编译提示

三、语义检查:你的话"说通"了吗?

定义

两个层次

四、对比表格

五、编译器报错信息怎么读?

六、嵌入式开发中的实际案例

案例1:寄存器地址写错(语义错误,语法完全正确)

案例2:类型不匹配的隐式转换

案例3:结构体对齐引发的语义问题

七、总结


一、一个比喻:老师改作文

你写了一篇作文交给老师。老师会检查两件事:

  1. 语法对不对——"我今天去学校" ✅ VS "我今天去学校学校去我" ❌
  2. 语义通不通——"我今天去学校" ✅ VS "我今天去月亮上吃火锅" ❌

编译器审你的 C 代码,也是同样的逻辑。

语法检查看的是"你写的句子符不符合 C 语言的句式"——就像改作文时先看句子通不通顺。

语义检查看的是"你写的代码在逻辑上有没有意义"——就像作文句子通顺了,还得看内容合不合理。

下面展开说。


二、语法检查:你的话"说对"了吗?

定义

语法检查(Syntax Check)检查代码是否符合 C 语言的语法规则——也就是你写的代码在"形式"上对不对。

编译器做了什么

源代码 → 词法分析(拆成单词) → 语法分析(检查排列顺序) → 语法树

典型语法错误

int a b; // ❌ 语法错误:两个标识符之间缺了逗号或分号 int 1a = 5; // ❌ 语法错误:标识符不能以数字开头 if (x > 5) // ❌ 语法错误:if 体必须跟语句 ; else // ❌ 语法错误:else 前必须有对应的 if y = 1;

编译器一看到这些,直接报语法错误(Syntax Error),拒绝往下编译。

典型编译提示

error: expected ';' before 'return' error: expected identifier or '(' before numeric constant error: stray '\243' in program

三、语义检查:你的话"说通"了吗?

定义

语义检查(Semantic Check)检查代码在逻辑上是否有意义——语法对了,但做的事合不合理。

两个层次

① 静态语义(编译阶段就能检测到):

int a = "hello"; // ⚠️ 语法上通过(赋值语句格式正确) // 但语义上:把字符串指针赋给 int,类型不匹配 int arr[5]; arr[10] = 3; // ⚠️ 语法正确,但语义上:数组越界 // 编译器可能只给 warning,甚至啥也不报 // 这是"未定义行为"的来源 void func(void); int x = func(); // ❌ 语义错误:void 函数不能有返回值

② 动态语义(运行时才暴露):

int *p = NULL; *p = 5; // ⚠️ 编译通过,运行时崩溃(空指针解引用) int x = 1 / 0; // ⚠️ 编译通过,运行时除零错误

静态语义能在编译时抓住一部分问题,但很多语义问题(空指针、除零、越界)只有运行时才暴露。


四、对比表格

对比维度语法检查语义检查
检查什么代码的"形式"是否正确代码的"含义"是否合理
类比句子有没有把单词排对句子的意思讲不讲得通
检查时机编译早期(词法→语法分析)编译中期(语义分析)+ 运行时
检测结果绝大多数在编译时报 Error部分编译时 Warning,部分运行时才暴露
例子int a b;缺分号int a = "hello";类型不匹配

五、编译器报错信息怎么读?

error: expected ';' before '}' → 语法错误(缺分号) warning: assignment from incompatible pointer type → 语义问题(类型不匹配) warning: unused variable 'x' → 语义问题(声明了没用) error: 'foobar' undeclared → 名字没定义

嵌入式小贴士:Keil MDK 的编译器对语法检查比较宽松,但对语义检查有些地方反而更严格(特别是 MISRA-C 规则)。建议定期用 GCC 编译一遍你的 STM32 代码,经常能发现 Keil 放过的 Warning。

养成读 Warning 的习惯,别只盯着 Error。Warning 经常是未来 Bug 的预报。


六、嵌入式开发中的实际案例

案例1:寄存器地址写错(语义错误,语法完全正确)

#define GPIOA_CRL (*(volatile uint32_t *)0x40020000) // 正确地址 #define GPIOB_CRL (*(volatile uint32_t *)0x40010C00) // ❌ 地址写错了 GPIOB_CRL = 0x11111111; // 语法正确,编译通过 // 但语义上:写到了错误的地址 // 这种错误编译器抓不到,debug 到哭

案例2:类型不匹配的隐式转换

uint8_t small = 255; uint16_t big = small + 1; // 语法正确,语义上 big = 256,没问题 // 但如果反过来: uint16_t big = 1000; uint8_t small = big; // ⚠️ 语法正确,语义上有截断风险 // small 实际等于 232(1000 - 256*3) // 编译器可能给 warning,也可能不吭声

案例3:结构体对齐引发的语义问题

#pragma pack(1) // 按1字节对齐 struct __attribute__((packed)) SensorData { uint8_t id; // 1字节 uint32_t value; // 4字节 }; // 总大小 = 5字节?还是8字节?

不同的编译器对结构体对齐的处理不同——语法上都是正确的,但语义上(内存布局)可能不一样。这在嵌入式通信协议解析中是常见坑。


七、总结

回到开头的作文比喻:

语法检查是语文老师看你有没有把字写对、把句子写通顺。通不过就退回去重写。

语义检查是数学老师看你算得对不对——句子通顺了,但"1+1=3"就是不对。

给初学者的建议:

  1. 看到 Error → 先看行号,再看是语法错还是语义错
  2. 看到 Warning → 当 Error 处理(养成-Wall -Wextra编译的习惯)
  3. 语义上的 Bug 比语法 Bug 难抓十倍——语法错编译器帮你挡了,语义错得自己 debug

最后说一句:编译器是你最好的朋友,不是敌人。它报的每条错误都在帮你。学会读编译器的"语气",能省掉大量 debug 时间。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 8:16:07

揭秘!儿童滑板车源头工厂哪家更值得信赖?

引言随着儿童户外运动的兴起,儿童滑板车市场日益火爆。然而,面对众多的源头工厂,家长们往往难以抉择。本文将深入分析,为您揭秘哪家儿童滑板车源头工厂更值得信赖。一、行业现状与痛点分析行业报告显示,目前儿童滑板车…

作者头像 李华
网站建设 2026/6/10 8:16:07

AI 模式在 SCA 工具中有什么价值?从风险解释到修复辅助说清楚

摘要AI 模式在 SCA 工具中的价值,不是替代安全专家,也不是自动修复所有漏洞,而是帮助安全团队和研发团队更快理解检测结果、判断风险优先级、获得修复辅助和完成协同沟通。对于企业软件供应链安全治理来说,SCA 的难点往往不在“发…

作者头像 李华
网站建设 2026/6/10 8:11:01

JavaScript实战③|图片懒加载与无限滚动,性能优化技巧

author: 专注前端开发,分享JavaScript干货 title: JavaScript实战③|图片懒加载与无限滚动,性能优化技巧 update: 2026-04-28 tags: JavaScript,实战项目,懒加载,无限滚动,性能优化,IntersectionObserver 作者:专注前端开发&#…

作者头像 李华
网站建设 2026/6/10 8:10:57

大学录取通知书上的二维码,扫出来是什么

高考录取通知书是很多人家里保存时间最长的证件之一。近几年,不少大学的录取通知书上开始印二维码。扫一扫,跳出来的页面里有什么?有学校的欢迎词,有入学须知,有时候还有一段视频。但这个二维码背后,连着的…

作者头像 李华
网站建设 2026/6/10 8:09:33

RV1126——多线程获取高分辨率和低分辨率的H264码流

前面两章我们已经搞定了单路 H264 码流获取、H264/H265 双编码码流获取。 都是固定分辨率取流,虽然能满足基础录像需求,但在真实的 IPC 摄像头项目中远远不够。实际项目里几乎全部是双分辨率方案: 一路高清 1080P做本地精细录像存档&#xff…

作者头像 李华
网站建设 2026/6/10 8:07:04

新乡高考志愿填报指导

每年高考结束后,新乡的考生和家长们都会面临一个重要的选择——志愿填报。这个过程不仅关系到未来几年的学习环境,更影响着长远的职业发展。然而,信息不对称、专业选择迷茫等问题常常困扰着大家。与那些只提供表面化建议的服务不同&#xff0…

作者头像 李华