预ANSI/ISO C转现代C时遭遇select函数参数不足错误的技术求助
解决
error: too few arguments to function ‘select’ 问题 让我帮你拆解这个问题,这里面其实有几个关键的错误点需要修正:
1. 编译器把你的自定义select当成了系统函数
现代C环境里,系统提供了一个用于I/O多路复用的POSIX函数select(),它的原型是:
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
需要至少5个参数,但你代码里调用的select(*mp++)只传了1个参数——编译器找不到你自定义的select声明,就默认把它当成了系统的select,所以报错参数太少。
解决办法:在调用pmode函数之前,或者在对应的头文件里声明你的自定义select函数,比如根据你的逻辑,它可能是这样的:
// 根据你的实际功能调整返回值和参数类型 void select(int *mode_ptr);
2. 指针循环的逻辑完全错误
看这段循环代码:
for (mp = &mp[0]; mp < &mp[sizeof(mp)/sizeof(mp[0])];)
mp是int **类型的指针,&mp[0]其实就是mp本身,而且sizeof(mp)是指针的字节数(比如64位系统是8字节),sizeof(mp[0])也是指针的字节数,所以sizeof(mp)/sizeof(mp[0])等于1,循环条件mp < &mp[1]永远为真,会无限循环还会越界访问内存,这是严重的bug。
你这里明显是想遍历一个指针数组,比如你有一个全局的int *modes[]数组,那正确的循环写法应该是:
// 假设这是你的指针数组 int *modes[] = { /* 填充你的指针元素 */ }; // 在pmode里遍历 for (mp = modes; mp < modes + sizeof(modes)/sizeof(modes[0]); mp++) { select(*mp); }
如果数组不是全局的,最好把数组和长度作为参数传入pmode,避免依赖全局变量。
3. 额外的小问题
- 现代C里不推荐使用
register关键字了,编译器会自动优化寄存器分配,直接写成int **mp;就行。 - 代码里的
flags变量看起来是全局的?如果不是,需要在pmode里声明或者作为参数传递,否则会报未定义错误。
修复后的示例代码
// 先声明自定义的select函数 void select(int *mode); // 假设你的指针数组定义在这里 int *modes[] = { /* 替换成你的实际指针元素 */ }; int flags; // 全局变量,或者改成参数传递 int pmode(int aflag) { int **mp; flags = aflag; // 正确遍历指针数组 for (mp = modes; mp < modes + sizeof(modes)/sizeof(modes[0]); mp++) { select(*mp); } // 根据你的函数逻辑返回合适的值,原代码没返回,现代C会警告 return 0; }
内容的提问来源于stack exchange,提问作者ZeroCool32
相关产品推荐
相关产品推荐

