My work place is developing code for some absolutely ancient hardware that doesn't have virtual memory. Because of this we're trying to be careful to minimize the text size of object and binary files, so we don't run out of memory. This likely means we'll need to limit the use of templates from the STL, or ban them outright. While looking around to find a way to minimize the size of our files, and still use templates, I came across the -frepo option for g++. A few tests later, I'm even more confused than when I started. The final binary file is the same size or larger when the -frepo is used, which doesn't make sense from me. Can anyone explain to me what this option actually does (other than "it just works," as that's the explanation from the GCC 4.7.1 manual) and how I might be abusing it?
Compiling with g++ -c -frepo main.cpp test8.cpp and linking with g++ test8.o main.o
The .rpo files arebeing created.
test8.h:
#include <list>
using namespace std;
class Test
{
public:
Test ();
list<int> makeNewIntList ();
private:
list<int> intList;
};
test8.cpp:
#include "test8.h"
#include <list>
using namespace std;
Test::Test()
{
intList = list<int>( 10, 12 );
}
list<int> Test::makeNewIntList()
{
intList.push_back(4);
return intList;
}
main.cpp
#include "test8.h"
using namespace std;
void findFive (int num);
list<int> makeIntList();
int main( int argc, char* argv[])
{
Test test;
list<int> intList = test.makeNewIntList();
list<int> intList2 = makeIntList();
list<float> floatList = list<float> (10,12);
floatList.push_back(5);
}
list<int> makeIntList()
{
list<int> intList = list<int> (10,12);
return intList;
}
We are using GCC 4.1.2. Also note GCC 4.7.0 isn't much better, and upgrading the compiler isn't a viable solution.
I would advise that you forget about -frepo, it's a relic and hardly used.
Instead you could look at the extern template syntax for declaring explicit instantiations, to prevent templates being instantiated implicitly, allowing you to control the instantiations so they only happen in one place. To be sure you don't miss any you could also compile with -fno-implicit-templates (which isn't necessary if you're rigorous about using extern template declarations everywhere necessary.)
Related
I'm trying to implement a thread-safe random number generator using an answer to a different post on this site. Xcode gives me a compile error in some system-provided source code. I've cut all the cruft out and this is the minimum code that will reproduce the error on the latest up-to-date Xcode.
#include <random>
#include <climits>
using namespace std;
mt19937 * _generator = NULL;
template <typename T> T ts_rand(void)
{
uniform_int_distribution<T> distribution(0, INT_MAX);
static bool fInited = false;
if (!fInited)
{
_generator = new mt19937();
fInited = true;
}
return distribution(_generator);
}
int main(int argc, const char * argv[])
{
int random_number = ts_rand<int>();
return random_number;
}
When I try to compile it, I get an error in the file 'algorithm', lines 2843 and 2865: "Semantic issue Type 'std::__1::mersenne_twister_engine * cannot be used prior to '::' because it has no members".
If I change _generator to be an actual instance instead of a pointer, it compiles fine. So that makes me think that there is something about this use of a templating that I don't understand, rather than an error in a system-provided file. FWIW, this same construct compiles and runs fine on VS 2013.
StackOverflow's suggested similar questions would seem to indicate that this might be related to VS' generous interpretations of incompletely-defined template classes, but I'm at a loss.
Any tips appreciated.
Your _generator is a pointer, but uniform_int_distribution::operator() expects a reference to a UniformRandomNumberGenerator.
You just need to do:
return distribution(*_generator);
#include <iostream>
#include <queue>
#include <string>
#include <vector>
using namespace std;
int main ()
{
struct process
{
int burst;
int ar;
};
vector<process> a;
// insert two processes
a.push_back({21, 42});
a.push_back({10, 20});
queue <process> names;
names.push(a[1]);
names.push(a[2]);
cout<<names.front().ar;
return 0;
}
The above code is working fine in eclipse but when i compile it on linux it give many errors. invalid argument and many more. i'm executing it with command:
g++ -o file_name file_name.cpp
does anyone know the reason behind these errors? any solution?
You need to move the definition of struct process out of the main function:
struct process
{
int burst;
int ar;
};
int main ()
{
...
}
Additionally, since you use initializer lists you must enable C++11 suport in GCC:
g++ -std=c++11 -o file_name file_name.cpp
You can not define a struct within a function. In your case, the struct process is defined within the main function.
Also, you need to declare the type of struct you wish to append to the vector.
the '{21, 42}' does not declare a 'process' type (Unless you use C++11).
Using local classes as template arguments and passing braced-init-list to functions are only possible as of C++11. Pass -std=c++11 or -std=c++14 option to g++ and all the errors will disappear. Note that all the letters in the option are in lower case.
I'm just starting to teach C++, coming from some other languages. I am wishing there were some way to consistently check the API created by a (student) file.
Suppose a student submits this file:
// this is stu.cpp
#include <iostream>
using namespace std;
double x(int y) {return y+0.5;}
Actually, suppose I asked the student to define some other function int x(int). I would like to be able to check this by running this code:
// this is stu.h
int x(int);
// this is gra.cpp
#include "stu.h"
#include <iostream>
using namespace std;
int main() {
cout << x(0); // test their code
}
So I am trying to see if the student's implementation matched the required interface, and testing it on input 0. I would have hoped this would not compile. But when I do
g++ -Wall -Wconversion *.cpp -o gra
./gra
It compiles and runs without crashing, giving output 0. This remains true even if I compile the two files separately and link them after.
I know that nm doesn't list return types. Is that the same reason that we can link together two files when the return values don't match? Is there any sane way to test this? (Like are there compile-time typeof assertions?)
Or is this a specific bug because of int and double being interconvertible? Are there additionall compiler options that could catch this?
Instead of compiling the student's code separately, why don't you just include it directly in your tester program?
int x(int);
#include <stu.cpp>
Then you should get a nice error like this:
a.cpp:2:8: error: functions that differ only in their return type cannot be overloaded
While this is not the "normal" way to compile a student's code, it guarantees that the code can be checked.
Alternatively, you may use a compiler command-line option like -include (GCC, Clang) to force the compiler to include a header file containing your desired API when compiling the student's C++ file. As an example:
api.h
int x(int);
compile with g++ stu.cpp -include api.h, and the appropriate error will be raised.
You can do the following:
// this is gra.cpp
#include "stu.h"
#include "stu.cpp"
#include <iostream>
using namespace std;
int main() {
cout << x(0); // test their code
}
And compile only gra.cpp of course.
I am aware there are numerous similar queries on here, however I haven't been able to resolve this, not has a colleague, so:
I am using MinGW (4.8.x) with Eclipse CDT Kepler.
1) I have my own code and to clean it up I changed it to use a vector of structs - all is fine, except that the function that receives it complains about Invalid Argument'.
2) I reduced my code down to a minimum working example, if I place it all in a single file it works, however if I move out my definitions to the header (which I need to do in my main code) it suddenly cannot resolve the fields in the struct...
The code below is for a three file configuration, header/function/main.
(In my main code I use namespace std - but that doesn't seem to be the problem. Also, there are extraneous headers for a minimum working example in this, however they are needed in my main code.)
myheaders.h
/*************************/
/****** myheaders.h ******/
/*************************/
/**-- Header Files --**/
// File Streams and IO
#include <stdio.h>
#include <sstream>
#include <iostream>
#include <fstream>
// For strtod -> string to double
#include <stdlib.h>
// Math Operations
//#include <math.h>
#include <cmath>
// To get the CPU time
#include <time.h>
// For Vectors
#include <vector>
// For strings, C strings right now...
#include <cstring>
// Needed globally for the function definitions
// using namespace std;
#ifndef MY_HEADERS
#define MY_HEADERS
struct SpeciesLoss {
int ReactionID;
int SpeciesID;
double coefficient;
};
std::vector< double > SpeciesLossRate(std::vector<SpeciesLoss> , int, const std::vector< double > & );
#endif
function.cpp
/*************************/
/****** function.cpp *****/
/*************************/
#include "myheaders.h"
std::vector< double > SpeciesLossRate(
std::vector< SpeciesLoss > SpeciesLossList,
int Number_Species,
const std::vector< double >& Combined_Rates
)
{
std::vector< double > temp_species_loss;
temp_species_loss.resize(1);
temp_species_loss[0]=SpeciesLossList[0].ReactionID;
return temp_species_loss;
}
main.cpp
/*************************/
/******** main.cpp *******/
/*************************/
#include "myheaders.h"
std::vector< SpeciesLoss > SpeciesLossAll; // New vector for recording species loss, uses a vector of structs
int main(int argc, char* argv[])
{
std::vector< double > Rates;
Rates.push_back(1);
SpeciesLossAll.push_back(SpeciesLoss());
SpeciesLossAll[0].ReactionID = 0;
SpeciesLossAll[0].SpeciesID = 0;
SpeciesLossAll[0].coefficient = 0;
std::vector< double > SpeciesConcentrationChange = SpeciesLossRate(SpeciesLossAll,1, Rates);
return 0;
}
Edit:
Screenshot
Edit 2:
And interesting update - it compiles fine on Linux with GCC. Better than nothing, but I still want to know what is going wrong, plus I'd like my code to be cross platform...
Edit 3:
This is more and more bizarre - I just tested my code (the full project that compiles on Linux) on my home PC which runs Windows 7 where it builds fine while my laptop runs Windows 8 and the problem occurs.
The Settings for the C++ build are absolutely identical.
Both run MinGW 4.8.1...
Both run the latest Eclipse Kepler...
And yes, I am aware that I need to test some suggestions still.
#ifndef MY_HEADERS
#define MY_HEADERS
Should be at the beginning of your file. Since you have no idea in what order the compiler is going to include headers this might be causing a problem... Especially if you are including your personal header in multiple files, wich will definitely make it behave like so. Also, keep in mind that since you are not providing a default constructor but rather using the one the compiler provides for you, those variables inside the struct will most likely not be initialized to zero as you expect them.
EDIT#1
Are you compiling everything NOT just main... I just copied your code into VS and it works!
EDIT#2
Try defining the function inline instead of a separate implementation file.
static std::vector< double > SpeciesLossRate(
std::vector< SpeciesLoss > SpeciesLossList,
int Number_Species,
const std::vector< double >& Combined_Rates
)
{
std::vector< double > temp_species_loss;
temp_species_loss.resize(1);
temp_species_loss[0]=SpeciesLossList[0].ReactionID;
return temp_species_loss;
}
EDIT#3
Ok, from the screen-shot this is definitely valid code. For sake of trying everything; implement your own constructor and copy constructor of the struct. I know this might sound silly but maybe Eclipse doesn't think so.
OK - I have found the answer - I think - and it boils down to Eclipse.
-> Project -> C/C++ Index -> Rebuild
This resolves the issue.
In fact, this problem is known on earlier Eclipse CDT versions: https://bugs.eclipse.org/bugs/show_bug.cgi?id=348170
When was the unordered_map concept built into g++?
Because the following code throws an error.
#include<iostream>
#include<unordered_map>
#include<stdio.h>
using namespace std;
std::unordered_map<std::int,int> mirror;
mirror['A'] = 'A';
mirror['B'] = '#';
mirror['E'] = 3;
int main(void)
{
std::cout<<mirror['A'];
std::cout<<mirror['B'];
std::cout<<mirror['C'];
return 0;
}
I am compiling the code as follows:
g++ -c hashexample.cpp
g++ -o result hashExample.o
./result
The error I got is this:
inavalid types int[char[ for aaray subscript
What is the fix for this?
The problem is your assignment. You cannot assign values to your map in this place. C++ is not a script language.
This program works fine on my machine with gcc4.6:
#include<iostream>
#include<unordered_map>
std::unordered_map<int,int> mirror;
int main() {
mirror['A'] = 'A';
mirror['B'] = '#';
mirror['E'] = 3;
std::cout<<mirror['A'];
std::cout<<mirror['B'];
std::cout<<mirror['C'];
}
First, as mkaes points out, you cannot put assignments outside functions, so you have to put it in any, for example main.
As for unordered_map, for recent versions of gcc, if you don't want to go into C++11, you can use the TR1 version of unordered_map:
#include <tr1/unordered_map>
and the type std::tr1::unordered_map. You know, C++11 supersedes all this, but you will (at least in GCC) get this working.