Getting a really weird compilation error with g++

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • liams
    New Member
    • Dec 2010
    • 26

    Getting a really weird compilation error with g++

    I have three files: main.cpp, Euler.h, and Euler.cpp. In Euler.cpp, I have a function that calculates prime numbers using Euler's sieve:

    Code:
    vector<int> sieve(vector<int>& primelist, int i)
    {
    	bool primes[i];
    	
    	primes[0] = false;
    	primes[1] = false;
    	
    	for (int j = 2; j < i; j++)
    		primes[j] = true;
    	
    	for (int j = 2; j * j < i; j++)
    	{
    		if (primes[j])
    		{
    			for (int k = j; k*j < i; k++)
    				primes[k*j] = false;
    		}
    	}
    	
    	for (int k = 2; k < i; k++)
    	{
    		if (primes[k])
    			primelist.push_back(k);
    	}
    }
    In Euler.h, I have the forward declaration for the sieve:

    Code:
    #ifndef EULER_H
    #define EULER_H
    
    #include <vector>
    #include "Euler.cpp"
    
    vector<int> sieve(vector<int>& primelist, int i);
    
    #endif
    And then in main.cpp, I have some code for testing my sieve function, through solving of one of Project Euler's problems:

    Code:
    #include <iostream>
    #include "Euler.h"
    
    using namespace std;
    
    bool isPrime(int check, const vector<int>& primes)
    {	
    	for (vector<int>::const_iterator it = primes.begin(); *it < check + 1; ++it)
    	{
    		if (*it == check)
    			return true;
    	}
    		
    	return false;
    }
    
    int main()
    {
    	vector<int> primes;
    	int max_co = 0;
    	int max_co_sec = 0;
    	int max = 0;
    	int x;
    	
    	sieve(primes, 1000);
    	
    	for (int a = -999; a < 1000; a++)
    	{		
    		for (int b = 0; b < 1000; b++)
    		{	
    			cout << "a " << a << " b " << b << endl;
    			
    			x = 0;
    			
    			while (isPrime(x*x+a*x+b, primes))
    				x++;
    				
    			if (x > max)
    			{
    				max = x;
    				max_co = a;
    				max_co_sec = b;
    			}
    		}
    	}
    	
    	cout << max_co * max_co_sec << endl;
    	
    	return 0;
    }
    But when trying to compile main.cpp, I am getting the following error:

    Code:
    In file included from Euler.h:5,
                     from main.cpp:2:
    Euler.cpp:1: error: expected constructor, destructor, or type conversion before ‘<’ token
    What could be causing this?
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    #ifndef EULER_H
    #define EULER_H

    #include <vector>
    #include "Euler.cpp"

    vector<int> sieve(vector<in t>& primelist, int i);

    #endif
    You do not put code in header files. That is, a header file is for declarations and other things that do not create variables or otherwise generate machine instructions.

    So it appears you do not need the Euler.h file. In main.cpp you should include <vector>. Then create the vector variable in main.cpp.

    Euler.cpp should compile as a second file of your build. If it needs the vector created in main.cpp, then you can declare an extern in Euler.cpp for that variable.

    Comment

    • liams
      New Member
      • Dec 2010
      • 26

      #3
      Thanks for the reply, but I'm still getting the same error. Code changed to this:

      /**REMOVED EULER.H**/

      main.cpp:
      Removed the Euler.h include, and instead put:
      Code:
      #include "Euler.cpp"
      #include <vector>
      In Euler.cpp, I added
      Code:
      extern
      to sieve().

      Other than that, everything is the same, but still same error.

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        Just an extern won't do it. You need to extern to the function in euler.cpp:

        Code:
        extern vector<int> sieve(vector<int>& primelist, int i);
        This is a function prototype and you need it in main.cpp.

        I got your code to compile after fixing this plus adding a return staement in the sieve function and allocting the primes array on th heap. C++ does not allow a stack array of i elements. That's a g++ add-on.

        To use only ANSI C++ you might try using the -pedantic switch.
        Last edited by weaknessforcats; Dec 22 '10, 06:08 PM. Reason: Typo

        Comment

        • liams
          New Member
          • Dec 2010
          • 26

          #5
          I added a function prototype in main.cpp, just as you said, but now I'm getting:
          Code:
          Euler.cpp:1: error: expected initializer before ‘<’ token
          Also, could you explain what you've done to get my code to compile? I'm not very familiar with the stack and the heap(I heard those terms, and I generally know what they are, but I don't -really- know what they do). Why doesn't C++ allow a stack array of i elements? And, why and how did you allocate the primes on the heap.

          p.s
          Tried compiling g++ -Wall -pedantic main.cpp, but there's no change in errors/warnings.

          Comment

          • weaknessforcats
            Recognized Expert Expert
            • Mar 2007
            • 9214

            #6
            Your function prototype uses vector. Did you #include <vector> before your prototype?

            C++ requires that the size of an array to be known at the time the array is created. If your array is a local variable then the compiler needs to know the size at compile time. Hence an array of i elements is not allowed.

            Local variables reside in memory in a thing called a stack frame. The compiler needs to know the size of the fram so it generate code to create a frame of the correct size. Local variables are said to be "on the stack" meaning that they are in the stack frame. The life an death of the variables is managed by the compiler so local variablea are aso called "automatic" variables.

            If you don't knoe the size of your array you can place a pointer variable on the stack and then allocate memory at run time. Here is where you use the "new" operator. Memory you allocate is said to be "on the heap". It also means you control the life an death of the variable so anything you allocate you are responsible to deallocate using the "delete" operator.

            Comment

            • liams
              New Member
              • Dec 2010
              • 26

              #7
              How do I do this in my code?

              Comment

              • weaknessforcats
                Recognized Expert Expert
                • Mar 2007
                • 9214

                #8
                My post #4 has the prototype you need in the file with main(). Just copy and paste it into your file.

                The linker will match the call in main() with the actual function in euler.cpp.

                Just be sure both files are part of the same build. That is, part of the same project,

                Comment

                • liams
                  New Member
                  • Dec 2010
                  • 26

                  #9
                  That is exactly what I did but it's not working. Maybe I'm not using correct compiling options. How do I tell g++ to correctly include it in my project?

                  Comment

                  • weaknessforcats
                    Recognized Expert Expert
                    • Mar 2007
                    • 9214

                    #10
                    Usually a file is in a project because you put it there.

                    Have you seen your make file? All of the files to compile and link must be in the make file.

                    I don't use g++ but I guarantee there is a simple way to add a .cpp file to a project. I use Visual Studio instead. Sorry I can't help furthere

                    Comment

                    • horace1
                      Recognized Expert Top Contributor
                      • Nov 2006
                      • 1510

                      #11
                      in the header file you need a using namespace statement
                      Code:
                      #ifndef EULER_H
                      #define EULER_H
                      
                      #include <vector>
                      
                      using namespace std;
                      
                      vector<int> sieve(vector<int>& primelist, int i);
                      
                      #endif
                      or specify the scope explicitly
                      Code:
                      #ifndef EULER_H
                      #define EULER_H
                      
                      #include <vector>
                      
                      std::vector<int> sieve(std::vector<int>& primelist, int i);
                      #endif
                      otherwise compilation fails as vector is an unknown identifer

                      to build the program I use the command
                      g++ main.cpp Euler.cpp

                      Comment

                      • weaknessforcats
                        Recognized Expert Expert
                        • Mar 2007
                        • 9214

                        #12
                        The "using namespace std" should be inside the functions in a C++ program and not in a header file. Otherwise whenever you include the header you assume namespace std is being used.

                        Usually, you see the "using namespace std" in each .cpp file and that is better than inside a header file. Ideally, though, the "using namespace std" should be inside each function in C++.

                        Comment

                        Working...