nunos nunos - 1 month ago 16
C Question

Warning: comparison with string literals results in unspecified behaviour

I am starting a project of writing a simplified shell for linux in C. I am not at all proficient with C nor with Linux that's exactly the reason I decided it would be a good idea.

Starting with the parser, I have already encountered some problems.

The code should be straightforward that's why I didn't include any comments.

I am getting a warning with gcc: "comparison with string literals results in unspecified behaviour" at the lines commented with "WARNING HERE" (see code below).

I have no idea why this causes an warning, but the real problem is that even though I am comparing an "<" to an "<" is doesn't get inside the if...

I am looking for an answer for the problem explained, however if there's something that you see in the code that should be improved please say so. Just take in mind I am not that proficient and that this is still a work in progress (or better yet, a work in start).

Thanks in advance.

#include <stdio.h>
#include <unistd.h>
#include <string.h>

typedef enum {false, true} bool;

typedef struct {
char **arg;
char *infile;
char *outfile;
int background;
} Command_Info;

int parse_cmd(char *cmd_line, Command_Info *cmd_info)
{
char *arg;
char *args[100];

int i = 0;
arg = strtok(cmd_line, " \n");
while (arg != NULL) {
args[i] = arg;
arg = strtok(NULL, " \n");
i++;
}

int num_elems = i;

cmd_info->infile = NULL;
cmd_info->outfile = NULL;
cmd_info->background = 0;

int iarg = 0;
for (i = 0; i < num_elems; i++)
{
if (args[i] == "&") //WARNING HERE
return -1;
else if (args[i] == "<") //WARNING HERE
if (args[i+1] != NULL)
cmd_info->infile = args[i+1];
else
return -1;

else if (args[i] == ">") //WARNING HERE
if (args[i+1] != NULL)
cmd_info->outfile = args[i+1];
else
return -1;

else
cmd_info->arg[iarg++] = args[i];
}

cmd_info->arg[iarg] = NULL;

return 0;
}

void print_cmd(Command_Info *cmd_info)
{
int i;
for (i = 0; cmd_info->arg[i] != NULL; i++)
printf("arg[%d]=\"%s\"\n", i, cmd_info->arg[i]);
printf("arg[%d]=\"%s\"\n", i, cmd_info->arg[i]);
printf("infile=\"%s\"\n", cmd_info->infile);
printf("outfile=\"%s\"\n", cmd_info->outfile);
printf("background=\"%d\"\n", cmd_info->background);
}

int main(int argc, char* argv[])
{
char cmd_line[100];
Command_Info cmd_info;

printf(">>> ");

fgets(cmd_line, 100, stdin);

parse_cmd(cmd_line, &cmd_info);

print_cmd(&cmd_info);

return 0;
}

Answer

You want to use strcmp() == 0 to compare strings instead of a simple ==, which will just compare if the pointers are the same (which they won't be in this case).

args[i] is a pointer to a string (a pointer to an array of chars null terminated), as is "&" or "<".

The expression argc[i] == "&" checks if the two pointers are the same (point to the same memory location).

The expression strcmp( argc[i], "&") == 0 will check if the contents of the two strings are the same.

Comments