关于 y0 y1 yn 变量名冲突说法的指正

前言

本文主要讲述变量名冲突的问题。

\\color{orange}免责声明

由于版本问题,您遇到的情况可能与我所讲述的不符,一切以本机版本为准,如果您遇到了其他问题,欢迎在评论区留下您的观点或遇到的问题。

即使现在变量名问题已经得到解决,我仍不建议大家在 NOI 系列比赛中使用这些变量名。

本人所用配置是:

  • Microsoft: Windows 10
    • Dev C++: 5.11
    • MingW64: 4.9.2
  • Linux stu: 20.04
    • Genay:1.36
    • MingW64:Ubuntu 9.4.0
  • Luogu IDE: C++14(GCC 9)

正文

引入

在机房颓的时候突然发现自己之前写的一道学校改编的入门考试题(原题在这里),

我这样写:

cpp 复制代码
double len(double x1, double y1, double x2, double y2){
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

按照现在的一般说法,这应该会 CE,因为 x1 y1 不能用作变量名。

但是它诡异地 AC 了。

?不是说不行吗?

于是 cao2333 开始了查资料 -> 验证 -> 不对 -> 查资料的循环......

前置知识:

  • #ifdef Value:和日常写代码时的 if() 很像,如果 Value 值为 1 则会执行下面的语句。
  • #ifndef Value:与 #ifdef 恰好相反,当后面的 Value 条件不成立时才会执行。
  • #endif:表示终止条件判断,与 #ifdef 和 #ifndef 连用。
  • #include<filename> 导入头文件
  • #define A B 宏定义,告诉编译器遇到 A 就当成 B。
  • #undef A 表示取消 #define 的宏定义。

cmath

cmath 文件是标准的数学库。在这个库中,包括了 abs(绝对值)sin cos tan (三角函数)ceil floor(向上/向下取整)等等十分好用的函数的指向。

有很多说法指出,x1 等变量名被占用是 cmath 头文件的锅。那么我们扒一下他的代码:

P.S. 省略 1600 多行代码。

......算了,还是用搜索吧。

搜索结果:未找到"x1"。

很好看来这个问题并没有出在 cmath 文件。

那么为什么很多人加了 cmath 会有问题、不加就没问题呢?

我们仔细审视一下 cmath 文件,发现这里的很多函数用几个模糊的大写字母来计算,大部分函数只有不到十行,这显然不足以完成仅仅推导式就要十几行的数学函数。

实际上,cmath 文件并不提供 部分 数学函数的解决办法,它的性质与 bits/stdc++.h 相似,都是将一些零散的头文件合并,并将深层头文件内容 、本文件中的额外附加 以及执行条件一并添加到你编写的程序中。

因此如果深层的头文件出现问题,依赖该文件的其他文件也会报错。

在 cmath 的开头部分中,我们找到以下代码:

cpp 复制代码
#pragma GCC system_header

#include <bits/c++config.h>
#include <bits/cpp_type_traits.h>
#include <ext/type_traits.h>
#include <math.h>

看来问题就出在这几个头文件里了。

math.h

经过搜索大法,问题出在 C:\Program Files (x86)\Dev-Cpp\MinGW64\x86_64-w64-mingw32\include\math.h 上。

math.h 文件中,存储了部分函数的定义、运算方式 和 大部分数学函数的指向 。包括但不限于 abs sin cos 等。

然后观察到:

cpp 复制代码
_CRTIMP double __cdecl j0 (double) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
_CRTIMP double __cdecl j1 (double) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
_CRTIMP double __cdecl jn (int, double) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
_CRTIMP double __cdecl y0 (double) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
_CRTIMP double __cdecl y1 (double) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
_CRTIMP double __cdecl yn (int, double) __MINGW_ATTRIB_DEPRECATED_MSVC2005;

这是现在的代码。如果你是报错的话,这一段大概率长这样:

cpp 复制代码
_CRTIMP double __cdecl j0 (double);
_CRTIMP double __cdecl j1 (double);
_CRTIMP double __cdecl jn (int, double);
_CRTIMP double __cdecl y0 (double);
_CRTIMP double __cdecl y1 (double);
_CRTIMP double __cdecl yn (int, double);

并不知道两段有什么区别

总之,可能是 MinGW 不知道何时更新了,现在定义变量名使用 x1 y1 x0 y0 都没有问题了。


拓展

虽然现在可以用这些变量名了,但是我还是有一些问题和有趣的发现:

这几个函数是干什么用的?

这个我已经没有时间和精力去递归式查找了,于是在这里贴出 Bing 搜索的结果:

\(j0,j1,jn\) 用于返回第一类贝塞尔函数解;

\(y0,y1,yn\) 用于返回第二类贝塞尔函数解;

什么是贝塞尔函数?

似乎在计算机学中还没有广泛使用?如果感兴趣的话可以去看看偶,没准你是下一个新算法的发明者。

为什么现在没事了?

是啊为什么?

由于机房的网是断开的,只能上几个限定网站,因此我也不知道 Bing 到的这个结果 中的解决办法是什么......

源代码打表

在 math.h 函数中:

cpp 复制代码
#define M_E		2.7182818284590452354
#define M_LOG2E		1.4426950408889634074
#define M_LOG10E	0.43429448190325182765
#define M_LN2		0.69314718055994530942
#define M_LN10		2.30258509299404568402
#define M_PI		3.14159265358979323846
#define M_PI_2		1.57079632679489661923
#define M_PI_4		0.78539816339744830962
#define M_1_PI		0.31830988618379067154
#define M_2_PI		0.63661977236758134308
#define M_2_SQRTPI	1.12837916709551257390
#define M_SQRT2		1.41421356237309504880
#define M_SQRT1_2	0.70710678118654752440

呵,想必大家都知道这片源代码在干什么吧......

赤裸裸的打表啊!

两个 math.h

在搜索时,C:\Program Files (x86)\Dev-Cpp\MinGW64\lib\gcc\x86_64-w64-mingw32\4.9.2\include\c++\tr1 路径下还有一份 math.h 文件。这份文件中有大量的 using tr1::...:: 代码。应该是 tr1 的实现代码。不知道是做什么的,今天按下不表。

变量名通缉单

在 cmath 文件中,断断续续出现了下列代码:
\\color{blue}过长,已折叠

cpp 复制代码
#undef abs
#undef div
#undef acos
#undef asin
#undef atan
#undef atan2
#undef ceil
#undef cos
#undef cosh
#undef exp
#undef fabs
#undef floor
#undef fmod
#undef frexp
#undef ldexp
#undef log
#undef log10
#undef modf
#undef pow
#undef sin
#undef sinh
#undef sqrt
#undef tan
#undef tanh

#undef fpclassify
#undef isfinite
#undef isinf
#undef isnan
#undef isnormal
#undef signbit
#undef isgreater
#undef isgreaterequal
#undef isless
#undef islessequal
#undef islessgreater
#undef isunordered

#undef acosh
#undef acoshf
#undef acoshl
#undef asinh
#undef asinhf
#undef asinhl
#undef atanh
#undef atanhf
#undef atanhl
#undef cbrt
#undef cbrtf
#undef cbrtl
#undef copysign
#undef copysignf
#undef copysignl
#undef erf
#undef erff
#undef erfl
#undef erfc
#undef erfcf
#undef erfcl
#undef exp2
#undef exp2f
#undef exp2l
#undef expm1
#undef expm1f
#undef expm1l
#undef fdim
#undef fdimf
#undef fdiml
#undef fma
#undef fmaf
#undef fmal
#undef fmax
#undef fmaxf
#undef fmaxl
#undef fmin
#undef fminf
#undef fminl
#undef hypot
#undef hypotf
#undef hypotl
#undef ilogb
#undef ilogbf
#undef ilogbl
#undef lgamma
#undef lgammaf
#undef lgammal
#undef llrint
#undef llrintf
#undef llrintl
#undef llround
#undef llroundf
#undef llroundl
#undef log1p
#undef log1pf
#undef log1pl
#undef log2
#undef log2f
#undef log2l
#undef logb
#undef logbf
#undef logbl
#undef lrint
#undef lrintf
#undef lrintl
#undef lround
#undef lroundf
#undef lroundl
#undef nan
#undef nanf
#undef nanl
#undef nearbyint
#undef nearbyintf
#undef nearbyintl
#undef nextafter
#undef nextafterf
#undef nextafterl
#undef nexttoward
#undef nexttowardf
#undef nexttowardl
#undef remainder
#undef remainderf
#undef remainderl
#undef remquo
#undef remquof
#undef remquol
#undef rint
#undef rintf
#undef rintl
#undef round
#undef roundf
#undef roundl
#undef scalbln
#undef scalblnf
#undef scalblnl
#undef scalbn
#undef scalbnf
#undef scalbnl
#undef tgamma
#undef tgammaf
#undef tgammal
#undef trunc
#undef truncf
#undef truncl

实测发现,在这张列表里涉及到的所有 #undef 后面的命名 全部有对应函数 ,都不能作为变量名。

后记

其实也算是颓了一个下午。有一种探案的感觉呢。不过在查资料的过程中,我发现了这样一个问题:

大家要么是查到资料解决问题就好,要么是发现问题避开问题,很少的巨佬会身先士卒追根究底、不找到根因不罢休。

我也不是什么巨佬啦,我的调查就到这里了,如果有很多人支持的话,我应该会出第二期 QwQ,如果有巨佬收到启发,希望诸位巨佬也要坚持到底呀!


\\\color{green}The\\;\\;End \\

相关推荐
~patience~10 小时前
WAV 逆向分析工具使用笔记
笔记
滴啦嘟啦哒10 小时前
【具身笔记】【π0.5 微调与仿真】五、在MuJoCo中实现可视化仿真
笔记·python·vla·具身
xier_ran10 小时前
【infra之路】AI 编译器学习笔记(十三):AI 编译器全景——TVM、XLA、IREE 与其他
人工智能·笔记·学习
连山齐名10 小时前
ai应用开发的学习笔记
服务器·笔记·学习
乔旭伟11 小时前
中小厂生产管理系统选型笔记:驱动方式、主线链路与成本结构
笔记·需求分析·规格说明书
xier_ran11 小时前
【infra之路】AI 编译器学习笔记(十四):为什么要 tiling,以及矩阵计算单元的“固定“
人工智能·笔记·学习
如旧呀11 小时前
origin绘制等距的HSD置信区间
笔记·origin
问心无愧051312 小时前
[极客大挑战 2019]Upload
笔记
蒸蒸yyyyzwd12 小时前
CMU 11-768 p1-3 笔记
笔记