是否存在可检测lambda捕获变量与形参重名的GCC编译选项
问题背景
现有测试代码中,标识符s同时作为lambda表达式捕获的外部变量、以及该lambda的形参存在,形参会遮蔽外层捕获的同名变量,在当前使用的g++环境及现有编译参数下,编译器未检测到该命名冲突,代码可正常编译但存在逻辑错误。
当前使用的gcc版本信息:
gcc (Debian 4.9.2-10+deb8u2) 4.9.2 Copyright (C) 2014 Free Software Foundation, Inc.
当前使用的编译参数:
-W -Wall -ansi -pedantic -s -march=native -flto -fwhole-program -Wfatal-errors -Wextra -std=c++1y -frename-registers -fipa-pta -Ofast -pedantic-errors -fira-loop-pressure -fomit-frame-pointer -fforce-addr -falign-functions -fno-cprop-registers -fstrength-reduce
存在问题的测试代码:
#include <vector> #include <algorithm> #include <iostream> int main (int argc, char* argv []) { int s (0); std::vector<int> vec ({3, 5, 13, 1}); std::for_each (vec.begin (), vec.end (), [&s] (const int& s) { s = s>s?s:s; }); std::cout << "max ox v is " << s << std::endl; }
可用检测方案
直接在现有编译参数中追加-Wshadow选项即可检测这类命名重名/变量遮蔽错误。
- 该选项在GCC 4.8及以上版本均已支持,完全适配你当前使用的GCC 4.9.2环境,开启后只要出现内层作用域标识符遮蔽外层作用域同名标识符的情况(包括lambda捕获变量和形参重名、局部变量和全局变量重名、内层局部变量和外层局部变量重名等场景),编译器就会抛出对应警告。
- 如果你希望这类问题直接阻断编译,可以同时追加
-Werror=shadow参数,将该类警告升级为编译错误;由于你当前开启了-Wfatal-errors,碰到第一个该类问题时编译器就会终止编译流程。 - 你给出的测试代码中,lambda内部所有
s都会被解析为lambda的形参,原本想要修改外部捕获变量s计算向量最大值的逻辑完全不会生效,属于典型的命名遮蔽导致的逻辑bug,-Wshadow可以精准识别该问题。
内容的提问来源于stack exchange,提问作者Saint-Martin
相关产品推荐
相关产品推荐

