以正确的结构调用编程例程…


我有一个问题可能会让你感到困惑,但同时也可能让我感到尴尬,但现在就这样吧。

让我们先看一些编程示例:

“C”例程的声明
int RetIntDayNum(char * datestrg, int * intdaynum, int * iostat);

声明实际的简单“C”例程。
int RetIntDayNum(char * datestrg, int * intdaynum, int * iostat) {
////



返回(1);
}

声明“C”调用:例程 1。
iretv = RetIntDayNum(cdatestring, &idaynum, &iostat);

声明“C”调用:例程 2。
iretv = RetIntDayNum(cdatestring, &idaynum);

好吧,问题是这样…
在调用“C”例程时,应使用“例程1”。 但在整理我的编程项目时,我后来发现
意识到我一直在使用“例程2”方法,并且每次编译这个程序时;
它编译正常并运行正常。

目前,我在 Windows 10 平台上使用 Enterprise MSVC 2019 环境。

我知道使用“例程 1”是正确的做法,但为什么使用“例程 2”却不能使程序正常运行
爆炸?。 为什么。 还是一场即将发生的爆炸?
目前,我必须回到这个大程序并修复所有程序错误。 但很困扰
我为什么“例程 2”方法不会导致程序现在崩溃(或异常终止)。

或者,一旦这一次,等待的爆炸会发生吗?
程序运行在完全不同的Windows平台上?

我好奇的心想知道……
再次感谢!

我尝试过的:

问题区域和我的编程项目中显示的内容。

解决方案1

这取决于编译器:当您尝试使用两个参数调用它时,大多数编译器都会给出错误“函数参数太少”。

除此之外,当您尝试在函数中使用 iostat 时,它可能会崩溃,因为它的值将是未定义的,并且您可能正在读取或写入内存的任何部分。

我会检查您使用的是什么 – MSVC 是 MicroSoft Visual C,它是一个独立产品,大约 20 年前成为 Visual Studio 的一部分,并且从未有过 2019 年版本。
我很确定 VS 2019 会因 C 程序的参数太少而抛出错误(可以在 C 中定义具有可变数量参数的函数 – 称为可变参数函数 – 但这需要特殊的语法和您如何使用它们是不同的)。

解决方案2

首先,必须区分实现中的声明和函数的调用。 下面这行不是声明而是赋值:

C
iretv = RetIntDayNum(cdatestring, &idaynum, &iostat);

如果 VS2019 找不到合适的调用实现,通常总是会生成错误。

的召唤

C
iretv = RetIntDayNum(cdatestring, &idaynum);

导致错误 C2198:“RetIntDayNum”:调用参数不足。
或错误 C2660:“RetIntDayNum”:函数不接受 2 个参数

由于 VS2019 是 C++ 编译器,因此可能会出现几个问题。
代码是否编译为 C 或 C++ 代码以及使用哪个编译器版本? VS2019基本上可以用以下标准编译:C++14、C++17、C++20、Legacy MSVC、std:c11、std:c17。

对于所描述的行为,我能想到的唯一解释是某个地方有另一个具有相同名称且只有 2 个参数的函数。
由于缺少参数而导致程序在(无错误)编译后是否会“爆炸”的问题无法回答,因为不知道这些函数实际上是做什么的。
无论如何,您只能访问编译器也可见的变量。 如果存在同名的全局变量,这可能会令人不快。

解决方案3

我简直不敢相信。 所以我尝试了下面的代码

C
#include <stdio.h>
  

int RetIntDayNum(char * datestrg, int * intdaynum, int * iostat);

int main()
{

  char foo[] = "foo";
  int daynum = 42;
  int iostat = 10;

  RetIntDayNum(foo, &daynum, &iostat);
  RetIntDayNum(foo, &daynum);

  return 0;
}


int RetIntDayNum(char * datestrg, int * intdaynum, int * iostat)
{
  printf("datestrg %s, intdaynum %d, iostat  %d\n");
  return 0;
}

在两个不同的平台上:

  • Linux 盒子,gcc 9.4
  • Windows 10、VS2022、CL 19.34

两个编译器都给出了 错误

  • 错误:函数“RetIntDayNum”的参数太少(gcc)
  • 错误 C2198:“RetIntDayNum”:调用参数太少(CL)

コメント

タイトルとURLをコピーしました