简体   繁体   中英

warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long int’ [-Wformat=]

This code is about.

Race conditions: Scheduling and compiler behaviour play a significant role in process or thread synchronization. The simplest scenario to demonstrate the need to synchronization comes from the race conditions created between two threads/process trying to modify a value of a shared variable, which typically results in data inconsistency, and erroneous results. The following example demonstrates this situation:

I'm new to C and am having trouble with what is happening with this warning. What does the warning mean and how can i fix it. The code i wrote is here:

q1.c: In function ‘runner’:
q1.c:13:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long int’ [-Wformat=]
 printf("T tid: %d x before: %d\n", syscall(SYS_gettid),x); int i;
 ^
q1.c:19:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long int’ [-Wformat=]
 printf("T tid: %d x after: %d\n", syscall(SYS_gettid),x);

Here's the code:

// Race condition
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/syscall.h>
int x=0;
void * runner(void *arg)
{
printf("T tid: %d   x before: %d\n", syscall(SYS_gettid),x); int i;
for (i = 0; i < 100000; i++ )
{
x = x + 1;
}
printf("T tid: %d   x after: %d\n", syscall(SYS_gettid),x);
}

int program()
{
pthread_t t1,t2,t3,t4;
printf("Parent pid: %d  x before threads: %d\n", getpid(),x); int i;
if(pthread_create(&t1,NULL, runner, NULL)){ printf("Error creating thread 1\n"); return 1;
}
if(pthread_create(&t2,NULL, runner, NULL)){ printf("Error creating thread 2\n"); return 1;
}
if(pthread_create(&t3,NULL, runner, NULL)){ printf("Error creating thread 1\n"); return 1;
}
if(pthread_create(&t4,NULL, runner, NULL)){ printf("Error creating thread 1\n"); return 1;
}

if(pthread_join(t1,NULL)){ printf("error joining thread 1"); return 1;
}
if(pthread_join(t2,NULL)){ printf("error joining thread 1"); return 1;
}
if(pthread_join(t3,NULL)){ printf("error joining thread 1"); return 1;
}

if(pthread_join(t4,NULL)){ printf("error joining thread 1"); return 1;
}
printf("Parent pid: %d  x after threads: %d\n", getpid(),x); return 0;
}

int main(int argc, char *argv[]) { 
int count=0;
// loop runs the program count times 
while(count<5)
{
// running program program();
count++;
//reset global x for next run of program. x=0;
printf("\n\n");
}
return 0;
}

你必须改变"%d""%ld""%d"是签署int和这里的l代表long这样"%ld"是有符号long int

Code should always be written with the idea of a human is going to read it. even the writer had significant problems reading the code as shown by the many 'copy-and-paste' errors

Note: when a '//' comment is started on a line, ALL the rest of the line is a comment

any functions, other than main, should have a prototype. The method of stating the called functions before any function that calls them will work for trivial programs, but not for multi file programs nor programs with crossing call paths IE always supply prototype statements.

When calling some function, always know (IE look it up) the full details about that function. In the case of the OPs posted code, this especially applies to the syscall() function.

When writing threads, there is more to know than just the prototype for a thread. As in the OPs code, also need to know how to exit the thread

ALWAYS ALWAYS enable all warnings when compiling. Warnings are problems in the code that should be fixed before continuing.

BTW: the use of a single mutex would have eliminated the race condition problem

// Race condition
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/syscall.h>

void *runner( void * );
int   program( void );

int x=0;


// <-- compiler raises warning about unused parameter
void * runner(void *arg)
{
    // the returned value from the syscall is a long int
    //printf("T tid: %d   x before: %d\n",
    printf("T tid: %ld   x before: %d\n",
            syscall(SYS_gettid),
            x);
    int i;

    for (i = 0; i < 100000; i++ )
    {
        x = x + 1;
    }

    // <-- the returned value from syscall is a long int
    //printf("T tid: %d   x after: %d\n",
    printf("T tid: %ld   x after: %d\n",
            syscall(SYS_gettid),
            x);

    // <-- this line missing, compiler raises warning
    pthread_exit(NULL);
} // end function: runner


int program()
{
    pthread_t t1,t2,t3,t4;

    printf("Parent pid: %d  x before threads: %d\n",
            getpid(),
            x);

    //int i; // <-- this variable not used, results in compiler warning


    if( pthread_create(&t1, NULL, runner, NULL) )
    {
        printf("Error creating thread 1\n");
        return 1;
    }

    if( pthread_create(&t2, NULL, runner, NULL) )
    {
        printf("Error creating thread 2\n");
        return 1;
    }

    if( pthread_create(&t3, NULL, runner, NULL) )
    {
        // <-- copy and paste error
        //printf("Error creating thread 1\n");
        printf("Error creating thread 3\n");
        return 1;
    }

    if( pthread_create(&t4, NULL, runner, NULL) )
    {
        // <-- copy and paste error
        //printf("Error creating thread 1\n");
        printf("Error creating thread 4\n");
        return 1;
    }


    if( pthread_join(t1, NULL) )
    {
        printf("error joining thread 1");
        return 1;
    }

    if( pthread_join(t2, NULL) )
    {
        // <-- copy and paste error
        //printf("error joining thread 1");
        printf("error joining thread 2");
        return 1;
    }

    if( pthread_join(t3, NULL) )
    {
        // <-- copy and paste error
        //printf("error joining thread 1");
        printf("error joining thread 3");
        return 1;
    }

    if( pthread_join(t4, NULL) )
    {
        // <-- copy and paste error
        //printf("error joining thread 1");
        printf("error joining thread 4");
        return 1;
    }

    printf("Parent pid: %d  x after threads: %d\n",
            getpid(),
            x);
    return 0;
} // end function: program


// <-- this line cause compiler to raise two warnings about unused parameters
//int main(int argc, char *argv[])
int main()
{
    int count=0;

    // <-- there is no loop code perhaps you meant to put the 'while' on the next line
    // loop runs the program count times while(count<5)
    while( count < 5 )
    {
        // <-- program is not run, perhaps you meant to put the 'program()' on the next line
        // running program program();
        program();

        count++;
        // <-- x is not being reset, perhaps you menat to put 'x=0;' on the next line
        //reset global x for next run of program. x=0;
        x=0;
        printf("\n\n");
    }

    return 0;
}  // end function: main

The prototype for syscall() returns a long

#include <sys/syscall.h>
long syscall(long number, ...);

When calling printf() , its format specifiers, like "%d" , should match the type of the parameter (after the parameter goes through the usual promotions for a variadic argument). Change to

                 v---- long --------v 
                              v----------- int ----------v
printf("T tid: %ld x before: %d\n", syscall(SYS_gettid), x);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM