2014-12-31 2 views
4

Этот код о.предупреждение: формат '% d' ожидает аргумент типа 'int', но аргумент 2 имеет тип 'long int' [-Wformat =]

Условия проведения соревнований: Планирование и поведение компилятора играют важную роль в синхронизации процессов или потоков. Самый простой сценарий, демонстрирующий необходимость синхронизации, исходит из условий гонки, созданных между двумя потоками/процессом, пытающимися изменить значение общей переменной, что обычно приводит к несогласованности данных и ошибочным результатам. Следующий пример демонстрирует эту ситуацию:

Я новичок в C, и у меня возникают проблемы с тем, что происходит с этим предупреждением. Что означает предупреждение и как я могу его исправить. Код я написал здесь:

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

Вот код:

// 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; 
} 
+3

Правильный отступ сделает ваш код * намного * более легким для чтения. –

+0

Обратите внимание, что copy'n'paste приводит к тому, что вы создаете (или не создаете) «поток 1» три раза и присоединяете (или не присоединяетесь) «поток 1» четыре раза. Помимо необходимости использовать массивы, вы также должны помнить, что полностью отредактируйте код при его повторном копировании. –

ответ

9

Вы должны изменить "%d" с "%ld", "%d" является для знакового int и здесь l стенды для long так "%ld" для подписанное long int.

0

Код всегда должен быть написан с идеей, что человек собирается его прочитать. даже автор имел серьезные проблемы с чтением кода , как показано на ошибки многих «скопировать и вставить»

Примечание: если «//» комментарий начинается на линии, все остальные линии является комментарий

любые функции, кроме основного, должны иметь прототип. Метод указания вызываемых функций перед любой функцией, которая их вызывает , будет работать для тривиальных программ, но не для многофайловых программ, а не для программ с пересекающимися дорожками вызовов I.E. всегда поставляйте утверждения прототипа.

При вызове какой-либо функции всегда знайте (I.E. посмотрите) все подробности об этой функции. В случае кода, опубликованного OPs, это особенно относится к функции syscall().

При написании тем есть больше, чем просто прототип для темы. Как и в коде OPs, также необходимо знать, как выйти из потока

ВСЕГДА ВСЕГДА включить все предупреждения при компиляции. Предупреждения - это проблемы в коде, который должен быть исправлен до продолжения.

КСТАТИ: использование одного мьютекса устранило бы неполадку состояние гонки

// 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 
0

Прототип syscall() возвращает long

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

При вызове printf(), его спецификаторы формата, как "%d" , должен соответствовать типу параметра (после того, как параметр проходит обычные рекламные акции для вариационного аргумента).Изменение на

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

Стоит отметить, что, хотя это было верно, так как примерно навсегда (https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=7f8116797fdb967571c00ec1d5b19d9d06813445 - фактически, 1996), документация была обновлена ​​только несколько месяцев назад (http://git.kernel.org/cgit/docs/man-pages/man-pages.git/commit/man2/syscall.2?id=24313b880d0b2785f89dadb029385967c639ddab), поэтому ошибки понятны. Сообщение об ошибке кажется мне совершенно ясным, но тогда я свободно говорю по-английски и C. :) – rici

Смежные вопросы

 Смежные вопросы