为什么编译器显示 "Call to function with no prototype"?
Why is the compiler showing "Call to function with no prototype"?
我正在尝试使用 DOS 视频内存打印字符串,但是当我调用函数 print_Id ();
和 (*old)();
时
它显示了这些警告,但没有 运行 代码,但没有这些功能一切正常。
调用没有原型的函数print_id
调用没有原型的函数
我把这个函数写在了最上面,但都是徒劳的。
请查看下面我的代码;我正在使用 BORLANDC 编译器。
#include<stdio.h>
#include<BIOS.H>
#include<DOS.H>
#include<conio.h>
int j;
void interrupt (*old)();
void interrupt print_name();
void interrupt print_Id();
char st[80] ={"Bilal Maqsood$"};
char id[20]={"BC110403231$"};
char far *scr=(char far* ) 0xb8000f3C;
int main( )
{
clrscr();
old=getvect(0x08);
setvect(0x08,print_name); //corrected
return 0;
}
void interrupt print_name(){
int i=0;
int j=0;
while(st[i]!='$'){
*(scr+j)=st[i];
*(scr+j+1)=0x72;
i++;
j+=2;
}
print_Id ();
}
void interrupt print_Id ( )
{
int i=0;
int j=0;
while(id[i]!='$'){
*(scr+j)=id[i];
*(scr+j+1)=0x17;
i++;
j+=2;
}
(*old)();
}
声明 void interrupt print_Id();
与 print_id()
不同,因为 i
的大小写不同。
因此,如果您调用 print_id()
而未在调用前声明或定义它,编译器将发出警告。
(虽然我在您发布的代码中没有看到 print_id
,包括调用...)
您应该收到针对三个声明的编译器警告:
void interrupt (*old)();
void interrupt print_name();
void interrupt print_Id();
这些声明了一个函数指针和两个函数。其中 None 在 C 中定义了一个原型。后两个声明函数的存在并且 return 类型是 void
(并且 interrupt
是 Borland 特定的或DOS 特定的干扰词)。但是空括号表示 "the argument list is undefined, except that it is not a variadic function — so there is no ...
ellipsis in the actual argument list".
要使它们成为原型,您需要明确指定函数不带参数:
void interrupt (*old)(void);
void interrupt print_name(void);
void interrupt print_Id(void);
这与 C++ 不同,其中空括号表示 'no arguments'。当 C 被标准化时,差异是必要的,因为原型在 C89/C90 标准之前不是 C 的一部分,并且所有现有代码都必须使用空括号来表示 "the function exists but you don't know anything about the function arguments" 并且标准会失败它破坏了所有现有的 C 代码。
之所以你只得到两次调用的警告,正是因为警告是在使用函数名或函数指针调用函数时产生的;当函数名称用作函数指针时不是。这三个都需要修复。
顺便说一句,我更喜欢让声明和定义保持一致,所以我也总是在函数定义中使用显式 void
参数列表;它确保函数定义提供一个原型,如果它也是独立的。
我正在尝试使用 DOS 视频内存打印字符串,但是当我调用函数 print_Id ();
和 (*old)();
时
它显示了这些警告,但没有 运行 代码,但没有这些功能一切正常。
调用没有原型的函数print_id
调用没有原型的函数
我把这个函数写在了最上面,但都是徒劳的。
请查看下面我的代码;我正在使用 BORLANDC 编译器。
#include<stdio.h>
#include<BIOS.H>
#include<DOS.H>
#include<conio.h>
int j;
void interrupt (*old)();
void interrupt print_name();
void interrupt print_Id();
char st[80] ={"Bilal Maqsood$"};
char id[20]={"BC110403231$"};
char far *scr=(char far* ) 0xb8000f3C;
int main( )
{
clrscr();
old=getvect(0x08);
setvect(0x08,print_name); //corrected
return 0;
}
void interrupt print_name(){
int i=0;
int j=0;
while(st[i]!='$'){
*(scr+j)=st[i];
*(scr+j+1)=0x72;
i++;
j+=2;
}
print_Id ();
}
void interrupt print_Id ( )
{
int i=0;
int j=0;
while(id[i]!='$'){
*(scr+j)=id[i];
*(scr+j+1)=0x17;
i++;
j+=2;
}
(*old)();
}
声明 void interrupt print_Id();
与 print_id()
不同,因为 i
的大小写不同。
因此,如果您调用 print_id()
而未在调用前声明或定义它,编译器将发出警告。
(虽然我在您发布的代码中没有看到 print_id
,包括调用...)
您应该收到针对三个声明的编译器警告:
void interrupt (*old)();
void interrupt print_name();
void interrupt print_Id();
这些声明了一个函数指针和两个函数。其中 None 在 C 中定义了一个原型。后两个声明函数的存在并且 return 类型是 void
(并且 interrupt
是 Borland 特定的或DOS 特定的干扰词)。但是空括号表示 "the argument list is undefined, except that it is not a variadic function — so there is no ...
ellipsis in the actual argument list".
要使它们成为原型,您需要明确指定函数不带参数:
void interrupt (*old)(void);
void interrupt print_name(void);
void interrupt print_Id(void);
这与 C++ 不同,其中空括号表示 'no arguments'。当 C 被标准化时,差异是必要的,因为原型在 C89/C90 标准之前不是 C 的一部分,并且所有现有代码都必须使用空括号来表示 "the function exists but you don't know anything about the function arguments" 并且标准会失败它破坏了所有现有的 C 代码。
之所以你只得到两次调用的警告,正是因为警告是在使用函数名或函数指针调用函数时产生的;当函数名称用作函数指针时不是。这三个都需要修复。
顺便说一句,我更喜欢让声明和定义保持一致,所以我也总是在函数定义中使用显式 void
参数列表;它确保函数定义提供一个原型,如果它也是独立的。