我使用Ideone.com编译了下面的代码,并弹出以下警告。
rtctimer.c: In function 'rtctimer_next_tick':
rtctimer.c:87.7: warning: ignoring return value of 'read',
declared with attribute warn_unused_result [-Wunused-result]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <poll.h>
#include <sched.h>
#include <fcntl.h>
#include <math.h>
#include <sys/ioctl.h>
#include <linux/rtc.h>
#include "rtctimer.h"
struct rtctimer_s
{
int rtc_fd;
int current_hz;
int rtc_running;
int verbose;
int usecs;
};
rtctimer_t *rtctimer_new( int verbose )
{
rtctimer_t *rtctimer = malloc( sizeof( rtctimer_t ) );
if( !rtctimer ) return 0;
rtctimer->verbose = verbose;
if( (( rtctimer->rtc_fd = open( "/dev/rtc", O_RDONLY ) ) < 0) ) {
if( rtctimer->verbose ) {
fprintf( stderr, "rtctimer: Cannot open /dev/rtc: %s\n",
strerror( errno ) );
}
if( ( rtctimer->rtc_fd = open( "/dev/misc/rtc", O_RDONLY ) ) < 0 ) {
if( rtctimer->verbose ) {
fprintf( stderr, "rtctimer: Cannot open /dev/misc/rtc: %s\n",
strerror( errno ) );
}
free( rtctimer );
return 0;
}
}
if( fcntl( rtctimer->rtc_fd, F_SETOWN, getpid() ) < 0 ) {
if( rtctimer->verbose ) {
fprintf( stderr, "rtctimer: Cannot set ownership of "
"/dev/rtc: %s\n", strerror( errno ) );
}
close( rtctimer->rtc_fd );
free( rtctimer );
return 0;
}
rtctimer->rtc_running = 0;
rtctimer->current_hz = 0;
rtctimer->usecs = 0;
return rtctimer;
}
void rtctimer_delete( rtctimer_t *rtctimer )
{
rtctimer_stop_clock( rtctimer );
close( rtctimer->rtc_fd );
free( rtctimer );
}
int rtctimer_next_tick( rtctimer_t *rtctimer )
{
unsigned long rtc_data;
struct pollfd pfd;
pfd.fd = rtctimer->rtc_fd;
pfd.events = POLLIN | POLLERR;
again:
if( poll( &pfd, 1, 100000 ) < 0 ) {
if( errno == EINTR ) {
goto again;
}
if( rtctimer->verbose ) {
fprintf( stderr, "rtctimer: poll call failed: %s\n",
strerror( errno ) );
}
return 0;
}
read( rtctimer->rtc_fd, &rtc_data, sizeof( rtc_data ) );
return 1;
}
int rtctimer_set_interval( rtctimer_t *rtctimer, int hz )
{
int restart;
if( hz == rtctimer->current_hz ) {
return 1;
}
restart = rtctimer_stop_clock( rtctimer );
if( ioctl( rtctimer->rtc_fd, RTC_IRQP_SET, hz ) < 0 ) {
if( rtctimer->verbose ) {
fprintf( stderr, "rtctimer: Cannot set periodic interval: %s\n",
strerror( errno ) );
}
return 0;
}
rtctimer->current_hz = hz;
rtctimer->usecs = (int) ( ( ( 1000.0 * 1000.0 ) / hz ) + 0.5 );
if( restart ) {
rtctimer_start_clock( rtctimer );
}
return 1;
}
int rtctimer_start_clock( rtctimer_t *rtctimer )
{
if( !rtctimer->rtc_running ) {
if( ioctl( rtctimer->rtc_fd, RTC_PIE_ON, 0 ) < 0 ) {
if( rtctimer->verbose ) {
fprintf( stderr, "rtctimer: Cannot start periodic "
"interrupts: %s\n", strerror( errno ) );
}
return 0;
}
rtctimer->rtc_running = 1;
}
return rtctimer->rtc_running;
}
int rtctimer_stop_clock( rtctimer_t *rtctimer )
{
int was_running = rtctimer->rtc_running;
if( rtctimer->rtc_running ) {
if( ioctl( rtctimer->rtc_fd, RTC_PIE_OFF, 0 ) < 0 ) {
if( rtctimer->verbose ) {
fprintf( stderr, "rtctimer: Cannot stop periodic "
"interrupts: %s\n", strerror( errno ) );
}
return rtctimer->rtc_running;
}
rtctimer->rtc_running = 0;
}
return was_running;
}
int rtctimer_get_resolution( rtctimer_t *rtctimer )
{
return rtctimer->current_hz;
}
int rtctimer_get_usecs( rtctimer_t *rtctimer )
{
return rtctimer->usecs;
}
int set_realtime_priority( int max )
{
struct sched_param schp;
memset( &schp, 0, sizeof( schp ) );
if( max ) schp.sched_priority = sched_get_priority_max( SCHED_FIFO );
else schp.sched_priority = sched_get_priority_max( SCHED_FIFO ) - 1;
if( sched_setscheduler( 0, SCHED_FIFO, &schp ) != 0 ) {
return 0;
}
return 1;
}
int set_default_priority( void )
{
struct sched_param schp;
memset( &schp, 0, sizeof( schp ) );
schp.sched_priority = 0;
if( sched_setscheduler( 0, SCHED_OTHER, &schp ) != 0 ) {
return 0;
}
return 1;
}
我做错了什么?
答案 0 :(得分:6)
read()
返回一个值,表示它读取的字节数。警告表明代码忽略了这一点。您应该检查read()
的返回值以确保它成功,否则您假设rtc_data
已正确填充且可能没有。
答案 1 :(得分:4)
你没有检查read
的返回值,这是一个等待发生的错误。
ssize_t r = read(rtctimer->rtc_fd, &rtc_data, sizeof( rtc_data ) );
if (r == -1) {
// deal with failed read
} else if (r != sizeof(rtc_data)) {
// you didn't read as much as you wanted to
...
如果不检查读取的内容,如果发生读取错误,程序将意外失败的可能性非常高,并且无法进行调试。 (第二种情况可能不适用于此特定示例,或某些管道读取。)
始终检查库调用的返回值,尤其是I / O,因为它们在正常情况下会失败。
答案 2 :(得分:1)
该行
read( rtctimer->rtc_fd, &rtc_data, sizeof( rtc_data ) );
产生一个结果(read()的返回值),你不以任何方式使用它,这会给你一个警告。这就是-Wunused-result
的目的。
忽略read()的返回值通常是一个非常糟糕的主意!