Take the following code:

#include <stdlib.h>


int main(int argc, char **argv, char **envp)
{ 
	int sum;
	atoi(&argv[1]);//statement with no effect.  Passing argument 1 of ‘atoi’ from incompatible pointer type
	atoi(&argv[2]);//statement with no effect.	Passing argument 1 of ‘atoi’ from incompatible pointer type
	sum = argv[1]+argv[2];  //error: invalid operands to binary +
	return sum;
}

On the lines with atoi(&argv[integer]) give me two warnings, statement with no effect, and passing argument 1 from atoi incompatible pointer type.

the line where I try to place the two argv members into a single integer by using addition gives me the error "invalid operands to binary".

Can anyone please explain to me why the comipler gives me this error and those four warnings? Thank-you.

Recommended Answers

All 15 Replies

Perhaps you mean to assign the return value of the atoi function to integers and add these integers instead of attempting to 'add' strings?

Yes, you're right. I changed the code:

int main(int argc, char **argv)
{ 
	int sum;
	sum = atoi(*(++argv));
        sum = atoi(*(++argv));
}

I honestly don't know if writing argv as an array or using this method plays any role on how the code will turn out, that is how unfamiliar I am with C.

this is a lot simpler

int main(int argc, char **argv)
{ 
    int sum = 0;
    int i;
    for(i = 1; i < argc; i++)
           sum += atoi(argv[i]);
}

Thanks Ancient Dragon. I think, however, that I'll keep my code the way it is until I'm sure that it works.

For right now, I'm wondering why I have the warnings for the following pieces of code:

main(int argc, char **argv, char **envp)
{//return type defaults to int

pair[k]=atoi(&argv); //warning: assignment makes integer from pointer without a cast

exec("worker.o", pair, envp); //implicit declaration of function 'exec'

}//warning: control reaches end of non-void function

Here are the following questions I have about my situation:

  1. Why is the compiler telling me that the default is return type is int?
  2. When it tells me that the assignment makes an integer from a pointer without a cast, does it mean I should use type-casting? What exactly is the problem here?
  3. When I make POSIX call exec, is a ".o" file an acceptable executable file? What does the g++ comipler mean by "implicit declaration"?
  4. Why does the compiler warn me of control reaching the end of a non-void function?

>Why is the compiler telling me that the default is return type is int?
Because the default return type (in fact, the standard) for main is int. It's supposed to be declared as int main( /* arguments */) . The compiler is warning you because you haven't explicitly declared the return type of main as 'int'.

>does it mean I should use type-casting? What exactly is the problem here?
Remember, argv[] is an array of pointers. You should give atoi the argument argv without the dereference operator, because you already have a pointer. You're trying to pass it a pointer of a pointer.

>implicit declaration of function 'exec'
You probably haven't included the header file unistd.h.

>is a ".o" file an acceptable executable file?
.o is typically an object file generated by a compiler before it gets to the linking stage, and as such, is not executable.

>Why does the compiler warn me of control reaching the end of a non-void function?
Your main function (which is supposed to return an integer) hasn't returned anything. On success, it should return either 0 or EXIT_SUCCESS, on failure it should return EXIT_FAILURE.

I appreciate the help thus far, but what exactly is "unistd.h."? What does this library allow me to do?
And, what is the meaning of error " undefined reference to exec"?

Oh, and by the way, I used unistd.h and it didn't change the warning at all.

>what exactly is "unistd.h."?
http://www.opengroup.org/onlinepubs/007908775/xsh/unistd.h.html

>Oh, and by the way, I used unistd.h and it didn't change the warning at all.
exec() isn't actually a function, it's a family of functions as defined in unistd.h. Since you're passing it environment variables, you'll want to use execle(). Finally, make sure you read up on the function carefully, because how you're calling it right now doesn't match the prototype of execle().

>what exactly is "unistd.h."?
http://www.opengroup.org/onlinepubs/007908775/xsh/unistd.h.html

>Oh, and by the way, I used unistd.h and it didn't change the warning at all.
exec() isn't actually a function, it's a family of functions as defined in unistd.h. Since you're passing it environment variables, you'll want to use execle(). Finally, make sure you read up on the function carefully, because how you're calling it right now doesn't match the prototype of execle().

How do I read up on exec? What, man exec in the terminal? I think I tried it with fork and it didn't work on my Debian Distro.

Thanks, I still don't have it figured out, but here's what I have thus far:

int main(int argc, char *argv[], char **envp)
{ 
	type_prompt();
	puts("Give me input numbers, each separated by space."); //gcc error: puts was not declared within this scope
	read_command(gets(), argv);  //warning:'implicit' declaration
	
	
	if((argc%2)==0)
	{
		int i = 1; /*counts down the length of argv*/
		while (i<argc)
		{
			while (1)
			{
				fork();
				if (fork()>-1)
					execve("worker.o", (atoi(*(argv)), atoi(*(argv++))), envp); //gcc error: undefined reference to exec
				/*Warnings for execve:
				 * left-hand operand of comma expression has no effect
				 * passing argument 2 of 'execve' makes pointer from integer
				 */
				i = i+2;
				break;
			}
		}
	}
	else 
	{
		int i = 1; /*counts down the length of argv*/
		while (i<argc-1)
		{
			while (1)
			{
				fork();
				if (fork()>-1)
					execve("worker.o", (atoi(*(argv)), atoi(*(argv++))), envp);
					/*Warnings for execve:
					 * left-hand operand of comma expression has no effect
					 * passing argument 2 of 'execve' makes pointer from integer
					 */
					i = i+2;
					break;
			}
		}
		fork();
		if (fork()>-1)
			execve("worker.o", (atoi(*(++argv)), 0), envp); //gcc error: undefined reference to exec
			/*Warning for execve:
			* passing argument 2 of 'execve' makes pointer from integer
			*/
	}
//	return sum = 0;  

}//warning: control reaches end of non-void function

I know I asked something like this somewhere before, but why is it telling me that "argument 2 of 'execve' makes pointer from integer"? Maybe it's wise I don't use atoi, to pass in the arguments to execve, but instead have my new process turn the argv arguments into integers.

I'm a referring to the original post here:

On this line:

pair[k]=atoi(&argv[i]);

You are actually passing in a pointer to a pointer while the function only takes a pointer. Remove the '&', this is whats causing a problem.

Maybe it's wise I don't use atoi

bingo.

next question: what is the point of all this? is it your entry into a Goldberg Machine contest?

bingo.

next question: what is the point of all this? is it your entry into a Goldberg Machine contest?

No, it's just some self-homework in my Operating Systems class I took in the spring. I didn't do as well as I had wanted to, so I'm trying to work on that now by working out the homeworks and trying to study up on the tests over the summer.

The point of this project is to better understand processes. I might have to take my project over to either a Solaris workstation or install Open Solaris on my computer, because, while reading my "Operating Systems" textbook, I found that Linux process scheduling is actually "thread-based" - which I don't understand.

All the POSIX calls should work, but the processes that I create will not work in the same way they would on a system that uses process-based scheduling.

What I ended up doing was using execv and didn't make any mention of environment because it doesn't require it. The question that I have now is, how do I specify exactly which process will have its core overwritten when I call an exec function?

For example, I make the call:

int childpid = fork();

then I use

execv("bin/child", commandArguments)

How does the system know which process I want changed? Does it matter?

Perhaps, since UNIX/Linux make use of fork calls and recognize parent processes and child processes, it automatically assumes that the child will be rewritten. Is that the case?

puts("Give me input numbers, each separated by space."); //gcc error: puts was not declared within this scope

You need to #include <stdio.h>, because that's where puts() is located.

The question that I have now is, how do I specify exactly which process will have its core overwritten when I call an exec function?

The current process will be overwritten.

So you have to make sure that exec*() isn't called from both the child and the parent of the fork(). :) You can do this by looking at the return value of fork() to tell if you're in the child or the parent. Then, only execute exec*() from the child. I don't know how exactly, but check the man page for fork, or use Google.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.