ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]? - g++

When I compiled the following program like:
g++ -O2 -s -static 2.cpp it gave me the warning ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result].
But when I remove -02 from copiling statement no warning is shown.
My 2.cpp program:
#include<stdio.h>
int main()
{
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",a+b);
return 0;
}
What is the meaning of this warning and what is the meaning of -O2 ??

It means that you do not check the return value of scanf.
It might very well return 1 (only a is set) or 0 (neither a nor b is set).
The reason that it is not shown when compiled without optimization is that the analytics needed to see this is not done unless optimization is enabled. -O2 enables the optimizations - http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html.
Simply checking the return value will remove the warning and make the program behave in a predicable way if it does not receive two numbers:
if( scanf( "%d%d", &a, &b ) != 2 )
{
// do something, like..
fprintf( stderr, "Expected at least two numbers as input\n");
exit(1);
}

I took care of the warning by making an if statement that matches the number of arguments:
#include <iostream>
#include <cstdio>
using namespace std;
int main() {
int i;
long l;
long long ll;
char ch;
float f;
double d;
//6 arguments expected
if(scanf("%d %ld %lld %c %f %lf", &i, &l, &ll, &ch, &f, &d) == 6)
{
printf("%d\n", i);
printf("%ld\n", l);
printf("%lld\n", ll);
printf("%c\n", ch);
printf("%f\n", f);
printf("%lf\n", d);
}
return 0;
}

Related

unresolved symbol pthread_create, first referenced in ./armrtk/src/task.obj

I have been trying to figure this out for a few days now and cannot figure it out. I am using CCS as the IDE and I am working on windows. I am trying to create an RTOS Kernel on a MSP432 and need to use pthreads. I have been able to use pthreads in other examples but I am trying to do my own program and I get this issue when building :
unresolved symbol pthread_create, first referenced in ./armrtk/src/task.obj
I have included the file path into CCS and I cannot use a .cfg file because I am not using XDCTools. I just need help with this and I greatly appreciate it.
I also get a warning:
in pthread_create in TASK.C: #169-D argument of type "void *" is incompatible with parameter of type "void *(*)(void *)"
TASK.H
#ifndef TASK_H
#define TASK_H
#include <pthread.h>
struct task_t {
pthread_t* thread;
int threadCheck;
int state;
};
void *task1(void);
void *task2(void);
struct task_t *create_task(void* functionptr);
void delete_task(void *task);
#endif
TASK.C
#include <task.h>
#include <stdlib.h>
#include <pthread.h>
#define BLOCKED -1
#define READY 0
#define RUNNING 1
int testValue1 = 0;
int testValue2 = 0;
struct task_t *new_task;
pthread_t pntr;
struct task_t *create_task(void* functionptr) {
new_task = malloc(sizeof(struct task_t));
if(!new_task)
return NULL;
//set State of the new thread to ready
new_task->state = 0;
// check to see if pthread is created
**new_task->threadCheck = pthread_create(new_task->thread, NULL, functionptr, NULL);**
if(new_task->threadCheck!= 0){
//thread failed
return NULL;
}
return new_task;
}
void delete_task(void *task) {
if(task != NULL){
free(task);
pthread_exit(NULL);
}
}
The unresolved symbol error is a linker error, not a compiler error. You have failed to link the pthreads library.
With respect to the warning functionptr is a void* where pthread_create() expects a pointer-to-function with signature void fn(void*).
Your task functions have a different signature in any case: void fn(void), so in any event you will need to cast the function pointer in the call to pthread_create() (although you are loosing a useful means of passing information into a task function by omiting the void* argument).
Modify task.h:
typedef void* (*task_t)(void);
struct task_t *create_task( task_t functionptr);
The in task.cpp
new_task->threadCheck = pthread_create( new_task->thread,
NULL,
(void (*)(void *))functionptr,
NULL ) ;
The cast in the pthread_create() call alone would supress the warning, but it bad form to pass a function pointer as a generic void* since it would prevent the compiler warning you if you were to pass anything other then a function pointer of the expected form to to the create_task()`

Storing int values in an uint8_t array in code composer studio vs 5.4

I have a string in a uint8_t str[] array and I am trying to store the positions of characters within the str in another variable called uint8_t pos[]. The code is written in Code Composer Studio vs 5.4
I tried using sprintf(), type casting as well as changing the type of uint8_t pos[] to int pos[] as well as unsigned int pos[]. None of these work.
The code breaks at the sprintf statement and comes to a halt by reaching an undefined memory location. When I run in assembly after reaching sprintf statement, it gives an error saying that a source code for sprint.c cannot be found in location.
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "tm4c123gh6pm.h"
#include <stdio.h>
void initHw()
{
.
.
}
int main(void)
{
// Initialize hardware
initHw();
char strRx[80];
int count =0;
int count_enter=0;
uint8_t posStr[80];
uint8_t typeStr[80];
int pos=0;
int len;
unsigned int j=0, argCount=0;
while(1)
{
if(count == 0)
{
putsUart0("Enter characters for the string\r\n");
}
if(count <= 80)
{
char c = getcUart0();
if(c=='\b')
if(count>0)
count--;
else
break;
if(c>=' ')
{
strRx[count]=c;
count++;
}
if(count==80 || c==13)//'\r')
{
count_enter++;
if(count_enter==1) //count==80 before carriage return
{
len = count;
strRx[count]='\0';
while(count!=80)
strRx[count++]='\0';
count_enter=0;
putsUart0("\r\nEntered string is:\r\n");
putsUart0(strRx);
putsUart0("\r\n");
}
j=0;
//char a[10];
for(pos=0; pos!=len; pos++)// strRx[pos]!='\0'; pos++)
{
char a[80];
if((strRx[pos]>='A' && strRx[pos]<='Z') || (strRx[pos]>='a' && strRx[pos]<='z'))
{
typeStr[j]='a';
//posStr[j]=pos;
a[j]=pos;
sprintf(a,"%u",pos); //source not found
//a[j]=pos;
//posStr[j]=sprintf("%c",a);
//posStr[j]=(uint8_t)a;//a;
while(strRx[pos]!='\0'&&((strRx[pos]>='A' && strRx[pos]<='Z') || (strRx[pos]>='a' && strRx[pos]<='z')))
{
pos++;
}
pos--;
j++;
}
else if(strRx[pos]>='0' && strRx[pos]<='9')
{
typeStr[j]='n';
a[j]=pos;
sprintf(a,"%u",pos);
//posStr[j]=pos;//a;
while(strRx[pos]!='\0'&&((strRx[pos]>='0' && strRx[pos]<='9')))
{
pos++;
}
pos--;
j++;
}
else
{
while(strRx[pos]!='\0'&&((strRx[pos]<'A' && strRx[pos]>'Z') && (strRx[pos]<'a' && strRx[pos]>'z') && (strRx[pos+1]<'0' && strRx[pos+1]>'9')))
pos++;
}
}
argCount=j;
while(j!=80)
{
typeStr[j++]='\0';
posStr[j++]='\0';
}
count = 0;
}//if(count==80 || c==13)//'\r')
}//if count<=80
}//while(1)
}//main
The "unable to locate sprintf.c" error probably just means that the debugger cannot locate the source file, which means it cannot show the source code in the debugger window. It's possible that you don't have the source code for sprintf.c and all you have is the precompiled library. Or maybe you do have the source code and the debugger is simply looking in the wrong path. If you have the source code then there may be a way to tell the debugger which path to find it.
But that is just a debugger display issue -- It is not what is causing your program to crash. The problem may be in your code but you'd have to share your code for us to identify that. Or the problem may be a couple other issues that can occur with the printf related routines.
1) printf routines can use a relatively large amount of stack space. So check for a stack overflow and increase the stack size if necessary.
2) Some embedded libraries provide multiple implementations of the printf routines such as "small", "no-float", and "full". The limited implementations use less code space but don't support all of the format specifiers. So make sure the implementation of sprintf that you've linked with supports all the format specifiers that you're actually using. Look through the project settings under linker or libraries for an option to select which version of printf is used.

failed to parse number by yacc and lex

i have finished my lex file and start to learn about yacc
but i have some question about part of my code of lex:
%{
#include "y.tab.h"
int num_lines = 1;
int comment_mode=0;
int stack =0;
%}
digit ([0-9])
integer ({digit}+)
float_num ({digit}+\.{digit}+)
%%
{integer} { //deal with integer
printf("#%d: NUM:",num_lines); ECHO;printf("\n");
yylval.Integer = atoi(yytext);
return INT;
}
{float_num} {// deal with float
printf("#%d: NUM:",num_lines);ECHO;printf("\n");
yylval.Float = atof(yytext);
return FLOAT;
}
\n { ++num_lines; }
. if(strcmp(yytext," "))ECHO;
%%
int yywrap() {
return 1;
}
every time i got an integer or a float i return the token and save it into yylval
and here is my code in parser.y:
%{
#include <stdio.h>
#define YYDEBUG 1
void yyerror (char const *s) {
fprintf (stderr, "%s\n", s);
}
%}
%union{
int Integer;
float Float;
}
%token <int>INT;
%token <float>FLOAT;
%%
statement :
INT {printf("int yacc\n");}
| FLOAT {printf("float yacc\n");}
|
;
%%
int main(int argc, char** argv)
{
yyparse();
return 0;
}
which compiled by
byacc –d parser.y
lex lex.l
gcc lex.yy.c y.tab.c –ll
since i just want to try something easy to get started, i want to see if i can parse
only int and float number first, i print them in both .l and .y file after i input an
integer or a float.int the begining i input fisrt random number, for example 123
, then my program print :
1: NUM: 123
in yylex() and
"int yacc\n"
in parser.y
but if i input the second else number, it shows syntax error and the program shutdown
i dont know where is the problem.
is there any solution?
Your grammar only accepts a single token, either an INT or a FLOAT. So it will only accept a single number, which is why it produces a syntax error when it reads the second number; it is expecting an end-of-file.
The solution is to change the grammar so that it accepts any number of "statements":
program: /* EMPTY */
| program statement
;
Two notes:
1) You don't need an (expensive) strcmp in your lexer. Just do this:
" " /* Do nothing */;
. { return yytext[0]; }
It's better to return the unknown character to the parser, which will produce a syntax error if the character doesn't correspond to any token type (as in your simple grammar) than to just echo the character to stdout, which will prove confusing. Some people would prefer to produce an error message in the lexer for invalid input, but while you are developing a grammar I think it is easier to just pass through the characters, because that lets you add operators to your parser without regenerating the lexer.
2) When you specify %types in bison, you use the tagname from the union, not the C type. Some (but not all) versions of bison let you get away with using the C type if it is a simple type, but you can't count on it; it's not posix standard and it may well break if you use an older or newer version of bison. (For example, it won't work with bison 3.0.) So you should write, for example:
%union{
int Integer;
float Float;
}
%token <Integer>INT;
%token <Float>FLOAT;

Use dlsym on a static binary

Is there any hope of running dlopen(NULL, ...) and getting symbols for a statically compiled binary?
For example, with the following code I can get symbols if the program is compiled dynamically and I use -rdynamic.
$ gcc -o foo foo.c -ldl -rdynamic
$ ./foo bar
In bar!
But with -static I get a cryptic error message:
$ gcc -static -o foo foo.c -ldl -rdynamic
/tmp/cc5LSrI5.o: In function `main':
foo.c:(.text+0x3a): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
$ ./foo bar
/lib/x86_64-linux-gnu/: cannot read file data: Is a directory
The source for foo.c follows:
#include <dlfcn.h>
#include <stdio.h>
int foo() { printf("In foo!\n"); }
int bar() { printf("In bar!\n"); }
int main(int argc, char**argv)
{
void *handle;
handle = dlopen(NULL, RTLD_NOW|RTLD_GLOBAL);
if (handle == NULL) {
fprintf(stderr, "%s\n", dlerror());
return 1;
}
typedef void (*function)();
function f = (function) dlsym(handle, argv[1]);
if (f == NULL) {
fprintf(stderr, "%s\n", dlerror());
return 2;
}
f();
return 0;
}
Is there any hope of running dlopen(NULL, ...) and getting symbols for a statically compiled binary?
No.
On most UNIXes you can't even link with -static and -ldl at the same time. Using glibc you can, but the utility of doing so is very limited. Basically, this ability is present only to support /etc/nsswitch.conf, and nothing else.
There is also no point in doing the dynamic lookup you did.
If you are trying to allow one of foo, bar or baz be called depending on command line arguments, just put a table in, e.g.
struct { const char *fname, void (*fn)(void) } table[] =
{ {"foo", &foo}, {"bar", &bar}, ...};
for (int i = 0; i < ...; ++i)
if (strcmp(argv[1], table[i].fname) == 0)
// found the entry, call it
(*table[i].fn)();
If you are trying to "maybe" call foo if it is linked in, and do nothing otherwise, then use weak references:
extern void foo(void) __attribute((weak));
if (&foo != 0) {
// foo was linked in, call it
foo();
}

Mingw32 std::isnan with -ffast-math

I am compiling the following code with the -ffast-math option:
#include <limits>
#include <cmath>
#include <iostream>
int main() {
std::cout << std::isnan(std::numeric_limits<double>::quiet_NaN() ) << std::endl;
}
I am getting 0 as output. How can my code tell whether a floating point number is NaN when it is compiled with -ffast-math?
Note: On linux, std::isnan works even with -ffast-math.
Since -ffast-math instructs GCC not to handle NaNs, it is expected that isnan() has an undefined behaviour. Returning 0 is therefore valid.
You can use the following fast replacement for isnan():
#if defined __FAST_MATH__
# undef isnan
#endif
#if !defined isnan
# define isnan isnan
# include <stdint.h>
static inline int isnan(float f)
{
union { float f; uint32_t x; } u = { f };
return (u.x << 1) > 0xff000000u;
}
#endif
On linux, the gcc flag -ffast-math breaks isnan(), isinf() and isfinite() - there may be other related functions that are also broken that I have not tested.
The trick of wrapping the function/macro in parentheses also did not work (ie. (isnan)(x))
Removing -ffast-math works ;-)