Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

bsavi

macrumors newbie
Original poster
Nov 13, 2011
12
0
Ok so per the suggestion of this forum I started using XCode which seems to be a pretty cool program so far. I am used to using Visual Studio 2010.

The problem that I have run into is that when I say
void main()
{

}

it tells me that main must be of type int. Why does main have to be of type int? Is there a setting somewhere that I am missing, I have looked at some sample code for Xcode and it seems that everyone uses main with int wich makes me feel like I am missing something.

Any help is appreciated!

Thanks,
Brad
 
Not really a problem with Xcode, more a problem with many texts and tutorials.

Xcode has a fairly good static anylizer that enfores the C standard requirement that main must return an int type as its result.

If you're doing 'C'

int main(void)

instead, or if doing 'C++'

int main()
 
The problem that I have run into is that when I say
void main()
{

}

it tells me that main must be of type int. Why does main have to be of type int?

Because that is what the C language says it must be.

If you bought a book that starts with "void main ()" throw it away. It demonstrates that the author doesn't care about getting things right.

If you write command line tools, the value that main () returns is used by the operating system as an error code, and using void main () will at best produce random error values.
 
And also it'll mean you'll need to end your main with:
Code:
return 0;

(BTW Yes, I know it should be return EXIT_SUCCESS; but I didn't want to confuse the noob with an extra #include).
 
Because that is what the C language says it must be.

If you bought a book that starts with "void main ()" throw it away. It demonstrates that the author doesn't care about getting things right.

If you write command line tools, the value that main () returns is used by the operating system as an error code, and using void main () will at best produce random error values.

I am currently in the begining classes of my computer science major and we are near the end of our C++ course and that is the way they have taught us thus far.

And also it'll mean you'll need to end your main with:
Code:
return 0;

(BTW Yes, I know it should be return EXIT_SUCCESS; but I didn't want to confuse the noob with an extra #include).

I understand C++ very well. The problem, more or less, is that switching to a different IDE seems to be more sensitive to smaller details that the teacher (who should have pointed them out) may have missed.

I'm never sure sure how many corrections should be piled on to new posters in a single post.

Pile them on! How else am I supposed to learn.
 
In that case any of the following may be correct, depending upon runtime environment.

Code:
#include <cstdio>

int main(void)                                      // no parameters - C
//int main()                                        // no parameters - C/C++
//int main(int argv, char* argv[])                  // with parameters - C/C++
//int main(int argv, char** argv)                   // with parameters - C/C++
//int main(int argv, char* argv[], char* envv[])    // with parameters, BSD - C/C++
//int main(int argv, char** argv, char** envv)      // with parameters, BSD - C/C++
{
    return EXIT_SUCCESS;
}
 
Mac OS X is based on BSD UNIX. in UNIX main is declared as:

int main(int argc, char *argv[])

When you create an XCode project it will generally create a folder called "Other Sources" which will contain a file called main.m. In this file main will be implemented as:

int main(int argc, char *argv[])
{
return NSApplicationMain(argc, (const char **) argv);
}

A compiler that will compile main() is old and not compliant with ANSI C because modern C requires full function prototypes. So it would have to be return_type main(void). Some old compilers would assume that a function with no return_type returned an int. Strict typing is a good thing that will save you a whole lot of trouble.
 
Mac OS X is based on BSD UNIX. in UNIX main is declared as:

int main(int argc, char *argv[])

When you create an XCode project it will generally create a folder called "Other Sources" which will contain a file called main.m. In this file main will be implemented as:

int main(int argc, char *argv[])
{
return NSApplicationMain(argc, (const char **) argv);
}

A compiler that will compile main() is old and not compliant with ANSI C because modern C requires full function prototypes. So it would have to be return_type main(void). Some old compilers would assume that a function with no return_type returned an int. Strict typing is a good thing that will save you a whole lot of trouble.

That was great! Thank you for the help!
 
One more

Ok so one more question then.

For any function that is written if it is void should it be written as an int or does that only apply for the main?
 
We're only talking about main here.

Ok just checking because every time I enter a write a function it gives me a warning that says
no previous prototype for the function 'function name'

Its a warning so I am not really worried about it but its just odd that its asking for a prototype.
 
Ok just checking because every time I enter a write a function it gives me a warning that says

Its a warning so I am not really worried about it but its just odd that its asking for a prototype.

There has to be a function prototype in like this:

return_type function_name(arguments);

This can be in the .c file or more often in a header.h file

Then the .h file has to be #included in the .c file like this:

#include "header.h"

Most compilers won't compile a function without a prototype.
 
Example -

Code:
#include <stdio.h>

// function declaration so the compiler knows what parameters need to be passed
// when called as well as the return-type
//
// in this case no parameters are passed to and no value is returned from the
// function 'otherfunction'

void otherfunction(void);


// function definitions must match declaration as above

void otherfunction(void)
{
}

int main(int argv, char* argv[])
{
    // call 'otherfunction', no paratmeters required and non returned

    otherfunction();

    return EXIT_SUCCESS;
}
 
I am currently in the begining classes of my computer science major and we are near the end of our C++ course and that is the way they have taught us thus far.

:eek:

I am a hobbyist programmer so take what I say with a grain of salt but I believe void main() worked back in the days before C++ was standardized.

I remember it working somewhere because I had the same question you did years and years ago and the answer I was given was that once C++ was standardized everything needed to use int main() not void main().
 
There has to be a function prototype in like this:

return_type function_name(arguments);

This can be in the .c file or more often in a header.h file

Then the .h file has to be #included in the .c file like this:

#include "header.h"

Most compilers won't compile a function without a prototype.

The skeleton of my code is as follows. The items in red are where I am generating that warning message.

Code:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include "Bst.h"

int main()
{
    void file();
    bool getAWord( fstream& textFile, string& word );
    void find(string& word );
    
    BinarySearchTree wordSort;
    ifstream fin;
    string textFile, word;
    int wordCount = 0;
    
    
}

[COLOR="Red"]void file()[/COLOR]
{
      \\CODE
}
[COLOR="red"]bool getAWord( fstream& textFile, string& word )[/COLOR]
{
      \\CODE
}
          
[COLOR="red"]void find(string& word )[/COLOR]
{
      \\CODE
}
 
Code:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include "Bst.h"

[COLOR="Red"]void file( void );[/COLOR]
[COLOR="Red"]bool getAWord( fstream& textFile, string& word );[/COLOR]
[COLOR="Red"]void find( string& word );[/COLOR]

int main()
{
    void file();
    bool getAWord( fstream& textFile, string& word );
    void find(string& word );
    
    BinarySearchTree wordSort;
    ifstream fin;
    string textFile, word;
    int wordCount = 0;
    
    
}

void file( void )
{
      \\CODE
}
bool getAWord( fstream& textFile, string& word )
{
      \\CODE
}
          
void find( string& word )
{
      \\CODE
}

Add the lines in red to get rid of the warnings you're seeing. Those are function declarations (as opposed to function definitions) and simply tell the compiler the function's name, return type, number of arguments, and argument types. You need them, because the compiler hits calls to those functions in main() before it has processed the function definitions themselves farther down in the file. Another way to get rid of the warnings would be to put the function definitions above main() so that the compiler has already seen them before it hits main() and sees calls to the functions.

With that explanation out of the way, the most common way of handling this is to have a separate .h file with function declarations in it. Then at the top of any .c file where you want to call those those functions, you #include the relevant .h file. .h files are called "header" files. This isn't so important if your entire program is in one source code file, but as your programs get more complex, you'll want to separate your code into multiple files for better organization and reusability. So in your case, you might do something like this:

File MyFile.h (name it the same as the .c file with a .h on the end):
Code:
// Note that main isn't declared. You could declare it,
// it's just that you never call it directly, so you don't really need to
void file( void );
bool getAWord( fstream& textFile, string& word );
void find( string& word );

In your MyFile.c file:
Code:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include "Bst.h"
[COLOR="Red"]#include "MyFile.h"[/COLOR]

int main()
{
    void file();
    bool getAWord( fstream& textFile, string& word );
    void find(string& word );
    
    BinarySearchTree wordSort;
    ifstream fin;
    string textFile, word;
    int wordCount = 0;    
}

void file( void )
{
      \\CODE
}
bool getAWord( fstream& textFile, string& word )
{
      \\CODE
}
          
void find( string& word )
{
      \\CODE
}

I hope this help explain things.
 
The skeleton of my code is as follows. The items in red are where I am generating that warning message.

You need to take the function declarations:

Code:
    void file();
    bool getAWord( fstream& textFile, string& word );
    void find(string& word );

and put them outside of the main() function. You can call functions in main(), but the function declarations have be put on their own, outside of any function.


So it should look like this:

Code:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include "Bst.h"

//Function Declarations
void file();
bool getAWord( fstream& textFile, string& word );
void find(string& word );

int main()
{ 
    BinarySearchTree wordSort;
    ifstream fin;
    string textFile, word;
    int wordCount = 0;
    
    //Call the functions here. They were declared above main,
    //so the compiler knows what they look like when it gets
    //to this point.
    file();
    if(getAWord(fin, word))
    {

    }

    find("text);
}

//Function Definitions
void file()
{
      \\CODE
}
bool getAWord( ifstream& textFile, string& word )
{
      \\CODE
}
          
void find(string& word )
{
      \\CODE
}

As for the void main() issue, putting void before main() was often done before C++ was standardized, so people who learned C++ before the standardization used both void main() and int main(). Compilers back then didn't complain about it because there was no official standard to follow. Each compiler behaved a little differently from the others. Now that there is a standard, main() is supposed to return an int so that the operating system knows whether there was an error in the program or not. Returning 0 means that there is no error, returning a non-zero value means that an error occurred. Other command line programs could then read the value being returned and respond appropriately.

My computer science professors taught us to use int main(), so when C++ was finally standardized I didn't have to change anything.

XCode 4 is enforcing the standard, so that's why it complains. Whatever other compilers you were using either are a bit lax in enforcing the standard or specifically allow void main() so pre-standard code doesn't break.

----------

mduser63 proposes an even more elegant solution than I did. My solution only works with a single file. When you write larger programs, and have to divide it up into multiple files, putting your declarations in header (.h) files allows you to call functions from another file without the compiler complaining. The compiler reads the header file first, knows which functions have been declared, so is able to compile calls to those functions, even if those functions are defined in another file.
 
You need to take the function declarations:

Code:
    void file();
    bool getAWord( fstream& textFile, string& word );
    void find(string& word );

and put them outside of the main() function. You can call functions in main(), but the function declarations have be put on their own, outside of any function.


So it should look like this:

Code:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include "Bst.h"

//Function Declarations
void file();
bool getAWord( fstream& textFile, string& word );
void find(string& word );

int main()
{ 
    BinarySearchTree wordSort;
    ifstream fin;
    string textFile, word;
    int wordCount = 0;
    
    //Call the functions here. They were declared above main,
    //so the compiler knows what they look like when it gets
    //to this point.
    file();
    if(getAWord(fin, word))
    {

    }

    find("text);
}

//Function Definitions
void file()
{
      \\CODE
}
bool getAWord( ifstream& textFile, string& word )
{
      \\CODE
}
          
void find(string& word )
{
      \\CODE
}

As for the void main() issue, putting void before main() was often done before C++ was standardized, so people who learned C++ before the standardization used both void main() and int main(). Compilers back then didn't complain about it because there was no official standard to follow. Each compiler behaved a little differently from the others. Now that there is a standard, main() is supposed to return an int so that the operating system knows whether there was an error in the program or not. Returning 0 means that there is no error, returning a non-zero value means that an error occurred. Other command line programs could then read the value being returned and respond appropriately.

My computer science professors taught us to use int main(), so when C++ was finally standardized I didn't have to change anything.

XCode 4 is enforcing the standard, so that's why it complains. Whatever other compilers you were using either are a bit lax in enforcing the standard or specifically allow void main() so pre-standard code doesn't break.

----------

mduser63 proposes an even more elegant solution than I did. My solution only works with a single file. When you write larger programs, and have to divide it up into multiple files, putting your declarations in header (.h) files allows you to call functions from another file without the compiler complaining. The compiler reads the header file first, knows which functions have been declared, so is able to compile calls to those functions, even if those functions are defined in another file.

BST.h contains most of the functions needed to call for this program. There is a very simple solution to the problem I am trying to solve but we are not allowed to use all the tools that are at our disposal which turns it into a thinking problem. It is interesting to learn the correct way to write things since a standard has been created. Actually it kind of pisses me off a bit being that I am paying for the information and am only getting kind of the right answers from the professor.

Thank you all for the help this helps a lot. As for the universal prototypes I will have to talk to my professor to see if he will allow that because in most casses he will not allow any universals. It may be a dumb rule but it is a rule that will get us a lower grade.

Thanks for the help!
 
Thank you all for the help this helps a lot. As for the universal prototypes I will have to talk to my professor to see if he will allow that because in most casses he will not allow any universals. It may be a dumb rule but it is a rule that will get us a lower grade.

I know the feeling, and of course you should follow the rules of the course, but it's fine to realize when they're stupid or wrong. As for universal (I presume you're using this as a synonym for "global"?) prototypes, there's a big difference between a global variable and a function declaration in a header file. A global variable is one that can be accessed from any scope in a program or particular source code file. They have their place, but it's often true that global variables are used by inexperienced programmers when there's actually a better way to structure their program. So, telling students to avoid global variables isn't unreasonable.

A function declaration in a header file is actually a good way of helping to write "encapsulated" code. You can put related code together in a source code and header file, then only include that header file in other source code files where the included functions are actually used. Sometimes, you'll want to have functions that are *not* available outside the source code file they're used in, to hide implementation details. In that case, you should put the declarations of those functions at the top of the .c file, and not in the .h file.

Again, do things the way your professor wants you too, but I hope you'll keep in mind that there's a lot of value in learning about the best ways to structure source code. When you start writing more complex programs, the details of the structure of your code become vary important in writing clear, well-design, code that's easy to read, understand and maintain.
 
I know the feeling, and of course you should follow the rules of the course, but it's fine to realize when they're stupid or wrong. As for universal (I presume you're using this as a synonym for "global"?) prototypes, there's a big difference between a global variable and a function declaration in a header file. A global variable is one that can be accessed from any scope in a program or particular source code file. They have their place, but it's often true that global variables are used by inexperienced programmers when there's actually a better way to structure their program. So, telling students to avoid global variables isn't unreasonable.

A function declaration in a header file is actually a good way of helping to write "encapsulated" code. You can put related code together in a source code and header file, then only include that header file in other source code files where the included functions are actually used. Sometimes, you'll want to have functions that are *not* available outside the source code file they're used in, to hide implementation details. In that case, you should put the declarations of those functions at the top of the .c file, and not in the .h file.

Again, do things the way your professor wants you too, but I hope you'll keep in mind that there's a lot of value in learning about the best ways to structure source code. When you start writing more complex programs, the details of the structure of your code become vary important in writing clear, well-design, code that's easy to read, understand and maintain.

Yes by universal I definitely meant global, I couldn't find the word. That is a great explanation, for one reason or another the teach likes to take the long way around the explanation of a topic. However I think your three paragraph response might have covered the entirety of one of my courses!
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.