- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我知道这很奇怪,但还是这样。
我正在管理一个非常古老的 ANSI C 之前的代码库。不管你信不信,下面的代码实际上是可以编译的。
myprog.c:
// Prototype.
int rec_index(); // Zero arguments.
kz = rec_index(1, 19, 2, 0, " ", 0, -1); // Seven arguments.
recindex.c:
int rec_index(flag, type, from, to, c, s, status, t) // Eight arguments.
int flag, type, from, to, s, status, t;
char *c;
{
printf("%d %d %d", flag, type, from);
if (flag < 0 || flag > 2) {
return -1;
}
if (type < 1 || type > 20) { // Line A.
return -1;
}
if ((flag == 1) && (type < 7 || type == 12 || type == 13)) { // Line B.
// Line C.
}
}
在 32 位环境中,这表现相当不错。函数定义中缺少的参数 t
被解释为零(或者更准确地说,它是未定义的),但这只包含在对该函数的一小部分调用中,而早已离开的开发人员知道在需要时包括在内。因此,当运行此代码时,输出将如预期的那样是前三个参数:
1 19 2
太棒了。该方法返回预期的行为。
但是……
我们最近开始将我们的软件移植到 64 位环境。在 64 位配置中,无论传递给函数的是什么,8 的第二个和第三个参数在函数中都被读取为零。
所以,在函数调用中传入1、19、2,检查函数内部的参数,Visual Studio报告为1、0、0。
1 0 0
奇怪的是,第四到第八个参数正确通过。只有第二个和第三个是错误的。
这就像站在某人旁边,拿一个空钱包,放入 3 美元,递给他们,他们打开钱包发现里面是空的。值(value)观去了哪里?
但它变得陌生了。我将 type
作为 19 传入,但该函数报告其值为零。 (这是通过检查内存位置 &type
来支持的。)让我们先看一下。
现在我们来到 recindex.c 中标记为 A 行的 if
语句:
if (type < 1 || type > 20) { // Line A.
由于调试器报告 type
为零,因此 ||
的左侧应该为真,这将使整个 bool 值短路为真,跳入大括号并导致 return -1;
。奇怪的是,这没有发生,调试器跳转到 B 行的下一个 if
:
if ((flag == 1) && (type < 7 || type == 12 || type == 13)) { // Line B.
同样,type
应该为零,flag
(实际上保持不变)为 1。这应该使整个 if
条件为真, 并陷入到 C 行的循环中。
指令指针按预期跳入循环,但 type
的值从 0 变为某个较大的值,始终不同,大约在 5000000 左右。 if
条件中的 NOTHING 有任何副作用,那么这个值是如何变化的?!
我猜想发生了某种堆栈损坏,这可能是由于非常不一致的函数原型(prototype)设计导致的未定义行为的结果。同样,这实际上在 32 位环境中有效,并且已经使用了 20 多年。
这里正确的答案是重写函数调用,以便全部采用八个参数,匹配函数声明,并使用像 int32_t
这样的类型而不是 int
所以我们可以确定尺寸。我可能会这样做。
但是,我很想解释为什么我会看到我现在的行为。
为什么输入函数后,函数的第二个和第三个参数被重写为零?
为什么其中一个参数的值虽然看起来为零,但在计算时却不像零?
当没有什么可以改变它时,是什么导致该值发生变化?
最佳答案
我想通了。
我提到(有点混淆)我正在调用这个函数:
int rec_index(flag, type, from, to, ck, sec, status, tert)
int flag, type, from, to, sec, status, tert;
char *ck;
{ … }
在我写的帖子中,对这个函数的调用是这样的:
kz = rec_index(1, 19, 2, 0, " ", 0, -1); // Seven arguments.
但为了避免在公共(public)互联网论坛上分享太多内部片段,我实际上解释了这个,真正的代码:
kz = rec_index(1, 19, trp->iztabl, 0, " ", 0, -1);
我假设不一致的原型(prototype)导致了损坏。当然不是——真正的问题在于第三个参数,trp->iztabl
。变量 trp
是 struct tran *
类型,一个指向结构的指针。在反省实际值并尝试取消引用它时,我发现 trp
是一个错误的指针。不是 NULL 指针,而是 BAD 指针——只是乱码,指向未知的内存区域。
当目标代码遇到一个错误的指针时,它要么不知道如何使用箭头运算符,要么更可能的是,它会转到由 trp
指定的内存中的适当位置并向前跳转与 iztabl
在结构中的位置对应的字节数。不过,人们会认为这只会返回乱码。
问题/编译器错误/普遍的烦恼是箭头运算符应用失败返回的值是一个 64 位指针,因为我们处于 64 位环境中,而不是 32 位 int trp->iztabl
已定义。由于对 rec_index()
的调用由彼此相邻的 32 位整数组成,因此插入 64 位指针的行为具有破坏性。这就是第二个和第三个参数消失的原因。 trp->iztabl
的返回值取出它自己的内存位置和它之前的那个(由于字节顺序)。
我看到的其他行为与值在调试器中被覆盖有关。我怀疑调试器的预期行为与此代码提供的不同,因此它在运行时感到困惑。
关于c - VS2010 中具有无参数原型(prototype)和 64 位架构的前 ANSI C,第二个和第三个参数消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22184851/
我正在寻找一个控制代码来使用 ANSI 或其他一些标准在终端中创建橙色文本,这可能吗?我只看到黄色和红色可用,我认为您不能将红色和黄色混合用于同一个角色:) 最佳答案 严格来说,不:ANSI 从未标准
我知道 \33[nC移动光标 n列向前;问题是,我不知道特定行包含多少个字符。 最佳答案 什么都没有显式 ,但是屏幕“小”,您可以使用任何光标移动命令移动到任意远的目的地,终端将通过屏幕大小限制移动。
这个问题在这里已经有了答案: Oracle Joins - Comparison between conventional syntax VS ANSI Syntax (11 个回答) 8 年前关闭。
我知道在 bash 终端中,一种可靠的变色方法是使用 ANSI 转义序列。例如: echo -e "\033[0;31mbrown text\033[0;00m" 应该输出 brown text (i
上次我检查时,说您正在使用 ANSI C 编码等同于说“这是符合 C99 的代码,其中没有任何其他内容”。现在有了 C11 和 C++11,这种区别还存在吗?它还有某种意义吗? 最佳答案 历史上,“A
我的业务逻辑包含在大约 7000 行 T-SQL 存储过程中,其中大多数都具有下一个 JOIN 语法: SELECT A.A, B.B, C.C FROM aaa AS A, bbb AS B, cc
我的业务逻辑包含在大约 7000 行 T-SQL 存储过程中,其中大多数都具有下一个 JOIN 语法: SELECT A.A, B.B, C.C FROM aaa AS A, bbb AS B, cc
我正在使用 CentOS 7 和 PHP 7.0 TERM=xterm-256color 我确实有一个彩色提示和 ls 颜色,如果我通过 --ansi然后它确实显示为彩色,但我不想总是添加 --ans
在我工作过的每家公司,我发现人们仍然按照 ANSI-89 标准编写 SQL 查询: select a.id, b.id, b.address_1 from person a, address b wh
我正在使用 Delphi RIO 10.3.3。 当我将 Ansi 字符串作为 const 数组的元素之一传递时,string() 转换对其不起作用。为了让它工作,我必须先将 VAnsiString
我正在使用 Delphi RIO 10.3.3。 当我将 Ansi 字符串作为 const 数组的元素之一传递时,string() 转换对其不起作用。为了让它工作,我必须先将 VAnsiString
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
当我在终端上调整大小时,它保持全屏显示。我想,有某种方法可以找出终端的屏幕尺寸。我怎样才能在 VT100 中做到这一点? 使用 ,当我列出文件夹时,它以蓝色显示文件夹。 (或者让我们说不同的颜色)但是
我的程序正在向某个日志文件发送characters-colored文本: echo -e "\\033[38;5;2m-->\\033[0m Starting program." | tee $Log
我刚开始使用 gsoap。我只使用 c++ 取得了 4 个小成功,但是我当前的项目限制了我设置源代码生成选项来创建纯 ANSI C(不是 c++)。我似乎无法成功调用该服务,错误返回为 0xC0000
来自 http://blocktronics.org/ 的 ANSI 文件似乎使用的是另一种 ANSI 编码,而不是我的 VT100 终端仿真器支持的编码。 如果我使用 tetraview 查看这些文
如何在 Java 中将十六进制字符串转换为 ansi(窗口 1252)以及将 ansi(窗口 1252)转换为十六进制字符串。 python(完美运行) q = "hex string value"
我用 java 编写了一个 android 应用程序来获取用户答案并将它们保存在一个文件中。问题是这个文件是以 utf-8 格式保存的。最终用户将在 IBM SPSS 中打开这些文件,这是一种适用于
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 7年前关闭。 锁定。这个问题及其答案
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicates: Floating point inaccuracy examples Is JavaScript's Ma
我是一名优秀的程序员,十分优秀!