Declared with attribute warn_unused_result [-Wunused-result]

I compiled the code below using Ideone.com and the following warning appeared.

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; } 

What have I done wrong?

+4
source share
3 answers

read() returns a value indicating the number of bytes read. A warning indicates that the code is ignoring this. You should check the return value of read() to make sure it was successful, otherwise you assume that rtc_data was correctly populated, and it may not have been.

+6
source

You do not check the return value of read , which is an error that only expects what will happen.

 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 ... 

If you do not check what you are reading, the probability is returned that your program will unexpectedly fail if a read error occurs and debugging is not possible. (The second case may not apply in this particular example or for some channel readings.)

Always check the return value of library calls, especially I / O, as they do not work under normal circumstances.

+4
source

Line

  read( rtctimer->rtc_fd, &rtc_data, sizeof( rtc_data ) ); 

creates a result (return value read ()), you are not using it in any way, this will give you a warning. The goal is -Wunused-result .

Ignoring the return value of read () is usually a very bad idea!

+1
source

Source: https://habr.com/ru/post/1394839/


All Articles