Programming Error, New to C++ - c++

I'm taking an intro class into C++ and we are using jgrasp. I'm doing a simple exercise right now which looks like this:
#include <iostream>
using namespace std;
int main()
{
cout << "Testing 1, 2, 3\n";
return 0;
}
though when I compile it and link it I get this error:
----jGRASP exec: g++ -c -fsyntax-only H:\COP2334\Excerises\Display 1.10
g++.exe: warning: H:\COP2334\Excerises\Display 1.10: linker input file unused because linking not done
----jGRASP: operation complete.

The option -c means "Compile or assemble the source files, but do not link."
So, of course, linking isn't performed.

Related

How To Run Google test from terminal on C code?

I am testing C code using googleTest.
My test.cpp file look like that
#include <gtest/gtest.h>
extern "C" {
#include "list.h"
#include "list.c"
}
TEST(ListTest, singleInsertion) {
// some tests
}
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
However trying to run the test from the terminal using
g++ test.cpp -lgtest gives Errors and warning as if the code being tested is C++ not C.
Error and warning Examples :
error: invalid conversion for mallocs and
warning: ISO C++ forbids converting a string constant to ‘char*'
how can I declare that my tested files are C not C++ ?
However trying to run the test from the terminal using g++ test.cpp -lgtest gives Errors and warning as if the code being tested is C++ not C.
That's because you are compiling it as C++ by using the g++ compiler. Use gcc to compile as C.
Unfortunately, this code won't compile as C - it'll choke on the google::InitGoogleTest() call because C doesn't recognize the :: scoping operator. I'm not familiar with this testing framework, but at first glance it looks like it's meant to be used with C++, not C.
The way to fix this is to remove the #include "list.c" directive
extern "C" {
#include "list.h"
}
and compile it separately as C:
gcc -c list.c
then compile your tester:
g++ -c test.cpp
and then link the object files with the library:
g++ -o test test.o list.o -lgtest

Trivial Eigen3 Tensor program does not build without -On

I'm trying to build a write of software with the Tensor module provided as unsupported from eigen3. I've written a simple piece of code that will build with a simple application of VectorXd (just printing it to stdout), and will also build with an analogous application of Tensor in place of the VectorXd, but WILL NOT build when I do not throw an optimization flag (-On). Note that my build is from within a conda enviromnent that is using conda-forge compilers, so the g++ in what follows is the g++ obtained from conda forge for ubuntu. It says its name in the error messages following, if that is perceived to be the issue.
I have a feeling this is not about the program I'm trying to write, but just in case I've included an mwe.cpp that seems to produce the error. The code follows:
#include <eigen3/Eigen/Dense>
#include <eigen3/unsupported/Eigen/CXX11/Tensor>
#include <iostream>
using namespace Eigen;
using namespace std;
int main(int argc, char const *argv[])
{
VectorXd v(6);
v << 1, 2, 3, 4, 5, 6;
cout << v.cwiseSqrt() << "\n";
Tensor<double, 1> t(6);
for (auto i=0; i<v.size(); i++){
t(i) = v(i);
}
cout << "\n";
for (auto i=0; i<t.size(); i++){
cout << t(i) << " ";
}
cout << "\n";
return 0;
}
If the above code is compiled without any optimizations, like:
g++ -I ~/miniconda3/envs/myenv/include/ mwe.cpp -o mwe
I get the following compiler error:
/home/myname/miniconda3/envs/myenv/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: /tmp/cc2q8gj4.o: in function `Eigen::internal::(anonymous namespace)::get_random_seed()':
mwe.cpp:(.text+0x15): undefined reference to `clock_gettime'
collect2: error: ld returned 1 exit status
If instead I ask for 'n' optimization level, like the following:
g++ -I ~/miniconda3/envs/loos/include/ -On mwe.cpp -o mwe
The program builds without complaint and I get expected output:
$ ./mwe
1
1.41421
1.73205
2
2.23607
2.44949
1 2 3 4 5 6
I have no clue why this little program, or the real program I'm trying to write, would be trying to get a random seed for anything. Any advice would be appreciated. The reason why I would like to build without optimization is so that debugging is easier. I actually thought all this was being caused by debug flags, but I realized that my build tool's debug setting didn't ask for optimization and narrowed that down to the apparent cause. If I throw -g -O1 I do not see the error.
Obviously, if one were to comment out all the code that has to do with the Tensor module, that is everthing in main above 'return' and below the cwiseSqrt() line, and also the include statement, the code builds and produces expected output.
Technically, this is a linker error (g++ calls the compiler as well as the linker, depending on the command line arguments). And you get linker-errors if an externally defined function is called from somewhere, even if the code is never reached.
When compiling with optimizations enabled, g++ will optimize away uncalled functions (outside the global namespace), thus you get no linker errors. You may want to try -Og instead of -O1 for better debugging experience.
The following code should produce similar behavior:
int foo(); // externally defined
namespace { // anonymous namespace
// defined inside this module, but never called
int bar() {
return foo();
}
}
int main() {
// if you un-comment this line, the
// optimized version will fail as well:
// ::bar();
}
According to man clock_gettime you need to link with -lrt if your glibc version is older than 2.17 -- maybe that is the case for your setup:
g++ -I ~/miniconda3/envs/myenv/include/ mwe.cpp -o mwe -lrt

"Duplicate symbol" when attempting to compile two .cpp files (from XCode) in terminal (MacOSX)

I have two .cpp files, main.cpp and secondFile.cpp:
#include <iostream>
int main()
{
std::cout << "Hello, World!\n" << std::endl;
std::cout << "I was also able to add this line!" << std::endl;
return 0;
}
And
#include <iostream>
int main()
{
std::cout << "This was from the second file!" << std::endl;
return 0;
}
I have successfully run g++ -o main.cpp main and g++ -o secondFile.cpp secondFile, as well as run each of their corresponding executables. However when I attempt to compile them simultaneously into a single executable g++ -o main.cpp secondFile.cpp bothScripts or clang++ main.cpp secondFile.cpp -o bothScripts I receive the following error:
"duplicate symbol _main in:
/var/folders/49/38grlkzs44zcth3v_dw9m9dm0000gn/T/main-d43536.o
/var/folders/49/38grlkzs44zcth3v_dw9m9dm0000gn/T/secondfile-2bee63.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)"
Clearly something is being loaded twice, but I am unsure whether this is a library (iostream), that I've named both sections 'main', or something else entirely. There are certainly questions similar to this already, but many are convoluted and not as fundamental for new C++ members (hence my question here).
Context: My rationale is to practice building executables from multiple .cpp files. Is there a better way to go about this? (New to C++ but not to programming/code as a whole.)
The reason for your error is simple. You have 2 main() functions. As you should know, in a C++ program, the function main() generally defines the entry point of a program. When each of the files are compiled together, and have their own main() function, the compiler gets confused and throws an error. To solve this, simply change the name of the main() function in one file, and call it from the other file, if you are planning to run them together.

compiling xerces-c++ program with Eclipse

I am trying to program with xerces-c on windows.
I have successfully built the library and compiled a simple program with success, barebone, with just cmd and notepad. However when I tried to move things to eclipse, things got a bit out of hand.
By simply having a c++ helloworld sample, then including the include files into the project path and build, eclipse is refusing to build the project, generating a lot of error, which I think mostly related to the namespace.
The errors goes as follow:
Info: Internal Builder is used for build
g++ -I...blablabla -O3 -Wall -c -fmessage-length=0 -o "src\\helloworld.o" "..\\src\\helloworld.cpp"
gcc -O3 -Wall -c -fmessage-length=0 -o "src\\includes\\xercesc\\util\\RefStackOf.o" "..\\src\\includes\\xercesc\\util\\RefStackOf.c"
..\src\includes\xercesc\util\RefStackOf.c:30:1: error: unknown type name 'XERCES_CPP_NAMESPACE_BEGIN'
XERCES_CPP_NAMESPACE_BEGIN
..\src\includes\xercesc\util\RefStackOf.c:35:10: error: expected '=', ',', ';', 'asm' or '__attribute__' before '<' token
template <class TElem>
^
..\src\includes\xercesc\util\RefStackOf.c:44:10: error: expected '=', ',', ';', 'asm' or '__attribute__' before '<' token
template <class TElem> RefStackOf<TElem>::~RefStackOf()
..\src\includes\xercesc\util\RefStackOf.c:...
...this and that, this and that.... and finally...
..\src\includes\xercesc\util\RefStackOf.c:160:1: error: expected '=', ',', ';', 'asm' or '__attribute__' at end of input
XERCES_CPP_NAMESPACE_END
and if I removed the file in error, error will just pop up to another file with the same format, beginning with "I dunno what XERCES_CPP_NAMESPACE_BEGIN means"
I have also tried using another builder, say mingw32-make, but it also generates error in the same format. Only changing the title a bit, and perhaps the files are compiled in different order, starting with this:
mingw32-make all
'Building file: ../src/includes/xercesc/util/BaseRefVectorOf.c'
'Invoking: GCC C Compiler'
gcc -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/includes/xercesc/util/BaseRefVectorOf.d" -MT"src/includes/xercesc/util/BaseRefVectorOf.o" -o "src/includes/xercesc/util/BaseRefVectorOf.o" "../src/includes/xercesc/util/BaseRefVectorOf.c"
../src/includes/xercesc/util/BaseRefVectorOf.c:24:1: error: unknown type name 'XERCES_CPP_NAMESPACE_BEGIN'
XERCES_CPP_NAMESPACE_BEGIN
I am guessing that the build program does not understand how to replace the
XERCES_CPP_NAMESPACE_BEGIN, with
namespace XERCES_CPP_NAMESPACE { }
namespace xercesc = XERCES_CPP_NAMESPACE;
But I don't know of a way to teach the builder how to do this, nor I am sure if I have compiled the library in the correct way.
Can someone point me in some direction as to how to solve this? I can compile a simple program by just using cmd, so certainly I should be able to do it in Eclipse.
background:
OS: Windows 8 64bit
compiler: mingw-w64 5.3.0 posix-seh-rev0
lib compiled with msys
lib compilation command:
./configure --prefix=/specific-location --host=x86_64-w64-mingw32 --enable-netaccessor-winsock --enable-transcoder-windows --disable-pretty-make
make LDFLAGS=-no-undefined
make check
make install
cmd compilation command: g++ -Llib -Iinclude -o b.exe test.cpp
so you can see that I have also included every xerces-c header into the compiler with the -Iinclude command, so I reckon that g++ should not produce error when invoked in Eclipse, not that I know anything if its gcc.
simple program that ran when simply compiled with cmd:
//test.cpp
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <iostream>
using namespace std;
using namespace xercesc;
int main (int argc, char* args[]) {
try {
XMLPlatformUtils::Initialize();
}
catch (const XMLException& toCatch) {
char* message = XMLString::transcode(toCatch.getMessage());
cout << "Error during initialization! :\n"
<< message << "\n";
XMLString::release(&message);
return 1;
}
XercesDOMParser* parser = new XercesDOMParser();
parser->setValidationScheme(XercesDOMParser::Val_Always);
parser->setDoNamespaces(true); // optional
ErrorHandler* errHandler = (ErrorHandler*) new HandlerBase();
parser->setErrorHandler(errHandler);
char* xmlFile = "x1.xml";
try {
parser->parse(xmlFile);
DOMDocument* xmlDoc = parser->getDocument();
DOMElement* elementRoot = xmlDoc->getDocumentElement();
if( !elementRoot ) throw(std::runtime_error( "empty XML document" ));
DOMNodeList* children = elementRoot->getChildNodes();
const XMLSize_t nodeCount = children->getLength();
cout << nodeCount << " nodes\n";
}
catch (const XMLException& toCatch) {
char* message = XMLString::transcode(toCatch.getMessage());
cout << "Exception message is: \n"
<< message << "\n";
XMLString::release(&message);
return -1;
}
catch (...) {
cout << "Unexpected Exception \n" ;
return -1;
}
delete parser;
delete errHandler;
return 0;
}
#EDIT
After further investigation, it seems that the XERCES_CPP_NAMESPACE_BEGIN is handled in preprocessor, but its only defined in the file util/XercesDefs.hpp
In the files with compilation error, they always begin with
#if defined(XERCES_TMPLSINC)
#include <xercesc/util/RefStackOf.hpp> //or include anything else blablabla, which ultimately leads to XercesDefs.hpp
#endif
I searched through the entire build directory for the string XERCES_TMPLSINC, it was contained in 44 .c or .hpp files, but everyone of them is #if !defined(XERCES_TMPLSINC) <===== WRONGWRONG , so like XERCES_TMPLSINC was never actually defined.
According to some forum post, XERCES_TMPLSINC was required for some old c compilers, so does anyone know how to fix this in my build? how could I define XERCES_TMPLSINC in the project? I have tried adding #define XERCES_TMPLSINC to the helloworld file but it still does not work.
#EDIT
my bad, actually all the .c files contained #if defined(XERCES_TMPLSINC) and all hpp files were #if !defined(XERCES_TMPLSINC), this definitely seems a c and c++ thing?
I was able to compile it in Ecliplse (on Linux) by adding the following preprocessor defs in g++:
-DXERCESC_INCLUDE_GUARD_WEAVEPATH_CPP -DXERCES_HAVE_STDINT_H -DXERCES_TMPLSINC.
On Windows I think you should substitute the with
-DXERCES_HAVE_STDINT_H -DXERCES_HAVE_CSTDINT

Getting compiler to work in Notepad++

I'm having some trouble using Notepad++ to compile code. I've installed notepad++ (and NppExec), downloaded MinGW from this source (http://nuwen.net/mingw.html) and installed it to "C:\MinGW\".
Then I tried to set notepad++ to use g++ to compile c++. Per advice, I entered the following into NppExec's console:
NPP_SAVE
CD $(CURRENT_DIRECTORY)
C:\MinGW\bin\g++.exe -g "$(FILE_NAME)"
Saved it as C++ Compiler, and added it to the "Macros" section of the toolbar.
Then I tried to run a simple test program:
#include <iostream>
int main()
{
cout << "Hello, world!";
}
After that a couple of weird errors popped up. First it wanted me to save to System32 by default, which I don't remember it doing before (it won't let me, forcing me to save in Documents).
I let it save to documents, than tried to run it with the compiler. It gives me this error, which I don't recognize at all:
NPP_EXEC: "C++ Compiler"
NPP_SAVE: C:\Users\Bova\Documents\Test.cpp
CD: C:\Users\Bova\Documents
Current directory: C:\Users\Bova\Documents
C:\MinGW\bin\g++.exe -g "Test.cpp"
Process started >>>
Test.cpp: In function 'int main()':
Test.cpp:5:5: error: 'cout' was not declared in this scope
cout << "Hello, world!";
^
Test.cpp:5:5: note: suggested alternative:
In file included from Test.cpp:1:0:
c:\mingw\include\c++\4.8.2\iostream:61:18: note: 'std::cout'
extern ostream cout; /// Linked to standard output
^
<<< Process finished. (Exit code 1)
Please help.
There is nothing wrong with your compiler. You are not using the correct namespace to use cout
#include <iostream>
int main()
{
std::cout << "Hello, world!";
}
Or
#include <iostream>
using namespace std;
int main()
{
cout << "Hello, world!";
}