C++ compiler

16 posts / 0 new
Last post
TheSLASH
TheSLASH's picture
Offline
Last seen: 12 years 10 months ago
Joined: 2011-12-27 00:50
C++ compiler

I found a example code, and want to compile it as C++, but there's some questions I have.
I'm from the PC world and have used Visual Studio and a little Linux (GCC), but the Visual Studio enviroment makes it a lot easier than have to fiddle around with make files... Ok, I'm now trying to use CodeBench, so I don't have to use shell at least... :)

Well, first is what "program" should I use for compiling, in the SDK:gcc/bin directory is there a lot of files, and what's the difference between the "g++" and "ppc-amigaos-g++"?
Is the "g++" for 68k processors and the other for the new X1000 (PPC), as the names almost say?!

The file "cpp" and "ppc-amigaos-cpp", what's that, the C++ compiler? I have searched in the GNU doc, but can't find some explanations of all files.

When I try to compile, I get these messages:

myfile.o:(.sbss+0x18): multiple definition of 'IExec'
myfile.o:(.sbss+0x1c): multiple definition of 'IDOS'

...and don't get these errors when I run the code as "C" (I think, atleast the original code and compiler settings). It may be the errors that Windows uses "#pragma once" for, but not sure, and I have only two files, the *.c and *.h file.

salass00
salass00's picture
Offline
Last seen: 6 months 2 weeks ago
Joined: 2011-02-03 11:27
gcc, g++ commands without

gcc, g++ commands without target prefix are used to compile binaries for the same system you are using whatever that is (since these are AmigaOS 4.x binaries from the AmigaOS 4.x SDK that system is ppc-amigaos aka AmigaOS 4.x).

ppc-amigaos-gcc, ppc-amigaos-g++, m68k-amigaos-gcc, m68k-amigaos-g++, i686-linux-gnu-gcc, etc. commands are used when you want to compile for a specific target system which may or may not be the same as the system you are compiling on (crosscompiling).

cpp is AFAIK just the C preprocessor used by gcc (you can use "gcc -E" also if you just want to see what the output from the preprocessing stage is).

kas1e
kas1e's picture
Offline
Last seen: 3 months 6 days ago
Joined: 2010-11-30 15:30
@TheSlash Well, first is

@TheSlash


Well, first is what "program" should I use for compiling, in the SDK:gcc/bin directory is there a lot of files, and what's the difference between the "g++" and "ppc-amigaos-g++"?

If you are on aos4 , then just use gcc/g++ (that just symlinks to ppc-amigaos-g++ and ppc-amigaos-gcc). But if you on crosscompiler, then you should of course use ppc-amigaos-g++ and ppc-amigaos-gcc , because on crosscompiler setup plain gcc/g++ will create a host-system bins, but not target (aos4) ones.


The file "cpp" and "ppc-amigaos-cpp", what's that, the C++ compiler? I have searched in the GNU doc, but can't find some explanations of all files.

ppc-amigaos-cpp, its just an amigaos version of cpp (just different name, and cpp are just symlink to ppc-amigaos-cpp). And it have the same purposes as everythere - preprocessing. You can easy live without (gcc/g++ by default use cc1 instead, which kind of the same by logic).

When you run gcc or g++, you run just a wrappers, which do preproccesing, object creating and linking. I.e. it use "cc1" for preprocessing and making assemble listing, then it use "as" to make a object (on aos4 "as" are symlink to ppc-amigaos-as), and then final linkage by "ld" (symlink to ppc-amigaos-ld). But when you use gcc/g++ wrappers that all done for you automatically, and you not need to worry about cpp/cc1/as/ld at all. You can check the full listing of really called programms and options which spawned to gcc/g++ wrappers via "-v" flag, i.e.:

gcc -v test.c -o test

Also for more detailed help you can use "-save-temps" , like:

gcc -save-temps test.c -o test

That will keep for you all files which done in the middle by gcc/g++ wrappers, and which used on the way from source file to executable one.

test.i - that one are preprocessed (by cc1, the same as cpp by logic)
test.s - assembly listing
test.o - object


When I try to compile, I get these messages

Upload your code somethere, so we can check.

@Salas00


cpp is AFAIK just the C preprocessor used by gcc (you can use "gcc -E" also if you just want to see what the output from the preprocessing stage is).

As far as i can see, i can just remove cpp and ppc-amigaos-cpp from SDK at all, and all still will works fine. What make me think, that by default only cc1/cc1plus are used for preprocessing, but not cpp.

TheSLASH
TheSLASH's picture
Offline
Last seen: 12 years 10 months ago
Joined: 2011-12-27 00:50
Thank you for the

Thank you for the explanaitions of the process....

So, should I use c++ for "C++" projects? The file cpp sounds like "C Plus Plus", but I can be wrong.... ..or is that a wrapper too, for the same proprocessor?

The code I'm playing around with is the "Lights" from OS4Depot, http://os4depot.net/index.php?function=showfile&file=demo/misc/lights.lha

I have moved all includes and the the variables that's not in a function/method (can't remember the correct word for C/C++). And changed some lines to:

roots = (int *)IExec->AllocVec( WWIDTH * WWIDTH * 2 * sizeof( int ), MEMF_ANY ); // inserted (int *)
float c = 0; // initialized it to 0, as the "animation" din't start without it, the value dind't increase with 'c += 0.02;' for some reason without it

...there may be more stuff that have to be updated to work with C++ from C, but two reasons why I want to go C++ is that I know it better, haven't really coded C, and these no "bool" in C (din't know that, and it's kind of important part, and the examples I have seen used enums (a bit odd)).

YesCop
YesCop's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2011-05-17 15:07
Hi, As said before, just use

Hi,
As said before, just use g++ to compile a C++ source on amiga.
Use C++ coding :
Well it is not mandatory, but it is cleaner. The C code from lights is not appropriate too much for C++ at last for me.
An another example is how the libraries pointer are passed to getLibIface (C method).

The Makefile use INLINE, I don't like to use it and write all the call, i.e:
IExec->MethodofIExec() in place of MethodofIExec(). So you will avoid conflict names sometimes.

For me, you must initialize each variable BEFORE using it (except if you calculate a new value). So float c=0 is NORMAL as you do a bit later c+=0.2.
If that worked without that, the memory was initialized during compiling (?) with gcc (compiling C). You should never let the compiler choose your starting values.

In general, coding from C to C++ on amiga is not difficult, little changes must me made because C++ is more "delicate" than C. Use warning option of g++ to debug your code and your code will be more perfect.

Good luck
YesCop

TheSLASH
TheSLASH's picture
Offline
Last seen: 12 years 10 months ago
Joined: 2011-12-27 00:50
How should I change the

How should I change the library pointers stuff to use ordinary C++?

I don't use the Makefile from the project, I use the one Codebench generated (after asking if I wanted to use the one in the archive) and it sets these compiler switches: -Wall -Werror -Wwrite-strings.

...I can't find MethodofIExec() in the code, or did I understand it wrong?

Yes, I know that all variable should be initialized, but in this case wasn't it so importants, as (in Windows) does the value goes round, if max value of double it will be just negative, and here should it just be a value that change (OK, haven't read all the code fully so don't know in detail what it does, yet). And I heard that some compilers set the default value to something like 0 when it run in debugmode and change it to the actual value i memory (could be anything) when run as release compile, and that's "dangerous".

I did change this line:

roots = IExec->AllocVec( WWIDTH*WWIDTH*2*sizeof( int ), MEMF_ANY );

to:

roots = new int[ WWIDTH * WWIDTH * 2 * sizeof(int)];

...hope that's correct. :)

But I still don't understand why I got this message:

lights.o:(.sbss+0x18): multiple definitions of 'IExec'
lights.o:(.sbss+0x1c): multiple definitions of 'IDos'

..I just have one *.h and *.c -file, or must the files be named *.hpp and *.cpp?

YesCop
YesCop's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2011-05-17 15:07
Wall -Werror warn you about

Wall -Werror warn you about potential errors (not always right, i.e. if you have uint t,u; t=u-2; u-2 could be negative so you have be warned). It is not a problem if you know what you do as always when you code !!
About initialized variable, I didn't understand your answer. Let's repeat my ealier explanation.
IN the code you have :
float c;
...
c+=0.2 <- this is equal to c=c+2 as you know, then as c is not initialized by you, you could have c equal to anything and not 0 as you expected.

When I reserved memory, I prefer to use new (remember to initialize it after ! :) )when I use C++ objects and allocvec or whatever specific amiga function when I use amiga objects.

Your error about multiple definitions of IExec seem to be normal, I had the same but at the moment, I don't remember what solutions I found. PM to me your last version of code and I will test it for you.
This error is not due to multiple files or suffix of filenames.
During compling, the compiler does not know what function to choose because of multiple definitions. If I remember well, my first tests had this error when compiling in C++ but not in C.

TheSLASH
TheSLASH's picture
Offline
Last seen: 12 years 10 months ago
Joined: 2011-12-27 00:50
Does this errors seems to be

Does this errors seems to be normal... Ok? The only thing I did was change the compiler to C++ and moved some code to a header file and added a "new" statement.... Shouldn't C++ be backward compatible, or isn't the C++ part of the Amiga so complete that it could really be used (only if you are a C++ expert) and most people uses C for that reason? It's a bit hard to start coding for the Amiga, as it seems... The OS is beta, have multiple GUI's and the C++ is not fully complete and there's no simple OS4+ examples to be found anywhere (what I found) and there's no IDE with simple debug capabilities. It's hard to know if it's my fault or some "incomplete stuff" that have to be worked around - and who know these secrets?

I really want to learn C++ coding on the Amiga, but it takes weeks to just be able to compile some simple stuff (from old(?) code).

salass00
salass00's picture
Offline
Last seen: 6 months 2 weeks ago
Joined: 2011-02-03 11:27
@TheSLASH lights.o:(.sbss+0

@TheSLASH


lights.o:(.sbss+0x18): multiple definitions of 'IExec'
lights.o:(.sbss+0x1c): multiple definitions of 'IDos'

IExec and IDOS are initialised by startup code so you don't have to open/close them in your own code unless you're writing something special like a .library, .device or a filesystem that can't use standard startup code. It is exactly as the error messages state, i.e. the IExec and IDOS global variables are defined both in lights.o and in the standard startup code which is automatically linked in by the compiler.

TheSLASH
TheSLASH's picture
Offline
Last seen: 12 years 10 months ago
Joined: 2011-12-27 00:50
Ok, so is that true for C

Ok, so is that true for C programs but not C++?

Could i just remove these lines and the code that opens the libraries?:

#include
#include

After some code I removed, i got this error:

sigs = IExec->SetSignal( 0L, 0L ); // Error: 'IExec' was not declared in this scope

And as i removed the openlibrary of IExec, how do i get access to SetSignal()?

kas1e
kas1e's picture
Offline
Last seen: 3 months 6 days ago
Joined: 2010-11-30 15:30
@TheSlash I download

@TheSlash

I download demo/misc/lights.lha, and all what i do, its check makefile, and then just do in the shell:

  1. gcc lights.c -o lights

All fine, no errors, programm works.

Then, i do compilation via c++ (as is that what you need), and:

  1. g++ lights.c -o lights

And have:

  1. lights.c: In function 'BOOL init()':
  2. lights.c:76: warning: deprecated conversion from string constant to 'char*'
  3. lights.c:77: warning: deprecated conversion from string constant to 'char*'
  4. lights.c:78: warning: deprecated conversion from string constant to 'char*'
  5. lights.c:91: error: invalid conversion from 'void*' to 'int*'

First 3 are problems-less, but you can removing warning by small change in code, but the most logical way for understanding, just write it from scratch, like this:

  1. // if( !getLibIFace( (struct Library **)&IntuitionBase, "intuition.library", 50, (struct Interface **)&IIntuition ) ) return FALSE;
  2. IntuitionBase = IExec->OpenLibrary("intuition.library",50L);
  3. IIntuition = (struct IntuitionIFace *) IExec->GetInterface (IntuitionBase,"main",1,NULL);
  4.  
  5. // if( !getLibIFace( (struct Library **)&GfxBase, "graphics.library", 48, (struct Interface **)&IGraphics ) ) return FALSE;
  6. GfxBase = IExec->OpenLibrary("graphics.library",48L);
  7. IGraphics = (struct GraphicsIFace *) IExec->GetInterface (GfxBase, "main",1,NULL);
  8.  
  9.  
  10. // if( !getLibIFace( &P96Base, "Picasso96API.library", 2, (struct Interface **)&IP96 ) ) return FALSE;
  11. P96Base = IExec->OpenLibrary("Picasso96API.library",2L);
  12. IP96 = (struct P96IFace *) IExec->GetInterface (P96Base,"main",1,NULL);

Code without errors checking, but that not matter here. Then i try to compile it again, and only one warning left, about void* to int* conversion. And the line are:

  1. roots = IExec->AllocVec(WWIDTH*WWIDTH*2*sizeof( int ), MEMF_ANY);

So, as it about invalid conversion from some to some, then i check "roots" value, and that is:

  1. int *roots

Then just add cast to the code:

  1. roots = (int *)IExec->AllocVec(WWIDTH*WWIDTH*2*sizeof( int ), MEMF_ANY);

The compilation again via g++, and as result no warning, no errors, but on compiling stage its say the same as you describe before: multiple definition of 'IExec' and of 'IDos'. So then i check again source, and see at top of file:

  1. struct ExecIFace *IExec;
  2. struct DOSIface *IDOS;

So, as linker say about multiply defination, that mean, that when c++ are used, then in startup libs (which adds automatically on building as i describe before) some code which already define IExec and IDos (by some reassons, for plain C compilation, startup code does not have those defines, or even if have, somehow get rid of those errors). So then i just comment them out, and then compilation was succesefull, linking was fine as well, and programm runs and works.

There is modifed code, compile it "g++ lights.c -o lights".

Anyway, prepare that you will have all the times problems of such kinds : i.e. no definations at all, or multiply ones, or wrong includes, or not all includes, or some warnings when migrate from c to c++, and you of course need to understand just whole idea of how all that compilators works, and then it all will be the same as i do: just step by step solving error by errror.

As for your other questions:


Shouldn't C++ be backward compatible

No

or isn't the C++ part of the Amiga so complete that it could really be used (only if you are a C++ expert) and most people uses C for that reason?

Those ones who want to use C , use C, who want to use C++ use C++. There is a lot of projects for os4 done just from scratch on C++ and that is not simple hello world, but just big projects.


It's a bit hard to start coding for the Amiga, as it seems...

No. Its hard because you do not know how gcc works, you do not know aos api, and you (seems) never migrate C to C++. Because casting problems are usuall, the same as words about multiply definations pretty common and on linux, and on win32, and everythere, if you by some reassons write that kind of code.

Maybe you choice bad code as first try, i told you before to get those ones from blog-posts (those reaction based hello-worlds).


The OS is beta, have multiple GUI's and the C++ is not fully complete and there's no simple OS4+ examples to be found anywhere (what I found) and there's no IDE with simple debug capabilities.

If you expect to see modern OS, with full-blown IDE+Debuggers+A-lot-of-uber-cool-documentation, its wrong choice. OS is small, developers not many and you for sure will have problems and limitations which you not have on win32 or even macos.

Gui toolkits are 2: reaction (official) and mui (3d party, but used on all the others amiga like oses, what can help if you want to make cross-compile app beetwen all amiga-like oses).


It's hard to know if it's my fault or some "incomplete stuff" that have to be worked around - and who know these secrets?

No secrets, just need to read what warning and erros say, then do google on them, and fix them in rigth way.

Better just try to write your own code, from scratch. All those "examples" which uploads everythere usually will give you problems, because of different reassons (like old version of SDK was used on moment of writing of example, or like old version of GCC was used, or old versions of startup libs). Example what you choice, are from 2004, so its luck that it still works.


Could i just remove these lines and the code that opens the libraries?

Exec library contain all the stuff which you use from Exec library. If you want to use AllocVec, which are in exec, then you of course can't remove includes, or how compiler will know where to get that functions ? To be note: that the same on all the oses, on all the compilators : if you want to use some function, you should add necessary includes.

YesCop
YesCop's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2011-05-17 15:07
Hi, I have just connected and

Hi,
I have just connected and see that someone very active gave you the solution to compile your program. I agree with all his advices he gave to you.
I will add this. I program on amigas for ages but since a few months I have decided to code specifically for OS4.1.
So if you want to code on amiga, first create non specific amiga code to test your C++ skills and imagination. When you decide to code some amiga lines, i.e. to open a window, to create some timers..., create a simple code to only code this and test it, test it again to learn how to use it in your big future atonishing program.
Then mix all the code.
This is not a new method to code, just avoid to have too many bugs to remove because that can be very painful in C++.
Take your time and gain experience reading others' source code upload around like OS4depot.
And of course, here are plenty of guys ready to help you.

Cheers,
YesCop

salass00
salass00's picture
Offline
Last seen: 6 months 2 weeks ago
Joined: 2011-02-03 11:27
And as i removed the


And as i removed the openlibrary of IExec, how do i get access to SetSignal()?

You do know that OpenLibrary and GetInterface are both exec.library functions? So opening exec.library is totally nonesense because to do so you would have to already have access to exec.library.

Anyway the way it's traditionally been solved in AmigaOS < 4.0 is that address 4 (AKA AbsExecBase) contains the pointer to exec.library's library base.

struct Library *SysBase;
SysBase = *(struct Library **)4;

In AmigaOS >= 4.0 the "main" interface pointer is stored inside SysBase and can be accessed like so:

struct ExecIFace *IExec;
IExec = (struct ExecIFace *)((struct ExecBase *)SysBase)->MainInterface;

Also in AmigaOS >= 4.0 direct access to address 4 although it works is discouraged and not necessary as the exec.library base pointer is provided as a parameter to the entry point of processes as well as the LibInit function of a .device or .library.

But this is all handled by startup code so you don't have to worry about it at all. Just include the relevant proto/ include files (proto/exec.h for exec and proto/dos.h for dos) and you will be able to use the library functions.

kas1e
kas1e's picture
Offline
Last seen: 3 months 6 days ago
Joined: 2010-11-30 15:30
@TheSlash Some more notice

@TheSlash

Some more notice to yesterday post:


I did change this line:
roots = IExec->AllocVec( WWIDTH*WWIDTH*2*sizeof( int ), MEMF_ANY );
to:
roots = new int[ WWIDTH * WWIDTH * 2 * sizeof(int)];
...hope that's correct. :)

When you want to change amigaos specific functions to some analogue but on plain C/C++, with or without usage of Posix, etc, all what you need its check necessary AutoDoc for (on amigaos all the libraryes have "autodoc" for it, which called by the same name as name of library). In which, all the functions of library listed, and every function of it described. So, for example in case with IEXec->AllocVec, you need to check exec autodoc (they in SDK), found function AllocVec, and read what is want as input, what it will return, and then by the same logic you make your analogues. Check on that site in coding-tools section Autodoc Viewers, they also can be helpfull , as they highlight necesary parts of autodocs.


..I just have one *.h and *.c -file, or must the files be named *.hpp and *.cpp?

You can have source and as .c and as .cpp, just when you will use gcc binary on .cpp, its still will call the g++ wrapper. But if you will have your file as .c , then for c++ you will need to use g++. I.e. you have 2 ways for compiling c++ progs:

  1. .cpp + gcc or g++
  2. .c + g++

That the same for all the oses, where is GCC present (unix,macos, win32 version of gcc)

TheSLASH
TheSLASH's picture
Offline
Last seen: 12 years 10 months ago
Joined: 2011-12-27 00:50
Thank you all for the

Thank you all for the answers, I'll have to read them many times to get all the bits... :)

And now does the code run, I had removed to much includes....

Two questions, the "startup code/libs" and "proto" stuff (as I allready asked and got a answer that I don't fully understand), is they AmigaOS(4) specific or is is something that I missed when study C++ programming?

kas1e
kas1e's picture
Offline
Last seen: 3 months 6 days ago
Joined: 2010-11-30 15:30
@TheSlash Startup

@TheSlash

Startup stuff

Startup code its code which adding by any compiler to the binary on the linking stage, which contain all the necessary "initialising os-related" code. For all the oses, for all the C/C++ compilers, you have those startup libs (for C/C++ that is objects, like crt0.o, crtS.o, crtbegin.o/crtend.o), just when you use gcc, you do not know about them (until you not meet with the erros or problems what will mean that you need to understant the crap). Or when you use win32 IDE inveronments, you also do not bother about. But still, and of course, they also used startup code objects, and you also can do compilation manually via : 1) preprocessing 2) object creating via assembler 3) linking with startup code objects (i.e. as i describe before).

CRT mean: C Run-Time (CRT) startup code. Thats why its all the time calls like crtXXXXX.o. On os4, when you compile a C programm, it's in reality do this:

  1. cc1 test.c -o test.s
  2. as test.s -o test.o
  3. ld test.o -o test /SDK/newlib/lib/crtbeing.o /SDK/newlib/lib/libc.a /SDK/newlib/lib/crtend.o

For c++ are the same, just for preprocessing uses cc1plus (that is the real difference beetwen c/c++ in terms of compilation : different preprocessing). Because of that different preprocessing, the startup objects/libs can behave differenly.

Those crtbegin.o and crtend.o are our crt startup objects, and libc.a are stub for c/c++ funcs. In your case , crtbegin.o behaves different after preprocessing done by the cc1plus in compare with cc1. Why ? Can't say to be honest. I do not have crtbegin.o sources, but pretty possible that its just differently reacts when source preprocessed by C (cc1) and by C++ (cc1plus).

If you really in interst to know why: you can use -save-temp as i say before, and check assembler source codes (i.e. compile one with gcc, and one with g++), so, you will found the differences and then will undestand why. I just compile it now to check, and size of course different, what meant that c++ preprosessing put different code.

To add about startup code, you of course can write your programms on assembler, withut startup codes at all, but ! As salas00 explain about SysBase, you should manually do minimal set of what crt startup objects do, like:

  1. .set ExecBase, 4
  2. .set MainInterface,632
  3.  
  4. .text
  5. .global _start
  6. _start:
  7. mflr r0
  8. stwu r1,-32(r1)
  9. stmw r28,8(r1)
  10. mr r31,r0
  11.  
  12. #get SysBase
  13. li r11, ExecBase
  14. lwz r3,0(r11)
  15.  
  16. #get Exec-interface
  17. lwx r30, MainInterface(r3) # r30 IExec
  18.  
  19. and then real code, like opening of libs, using of functions of that libs and so on.

But as you on C/C++, all the stuff done by startup code, and you do not need to worry, until you want dig in deep, and understand low-level details. You just use gcc/g++ wrappers, which use all the stuff, and include/add all necessary startup code / stub libs and so on.

Proto stuff

Protos are amigaos specific, they are "describe" for you aos apis which you can use. For example when you want to use plain C functions from ansi C, or from posix, you use something like:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. and so on

When you use let's say any 3d party toolkits, which non os specific (like SDL, Allegro, OpenGL), you also just use it the same way as on any oses):

  1. #include <SDL/SDL.h>
  2. #include <Allegro/Allegro.h>
  3. #include <OpenGL/gl.h>

And only with amigaos functions you need to specify necessary proto files. If you want to use exec library functions, you do #include <proto/exec.h>. If you want dos library, you use #include <proto/dos.h>. If you want reaction, you include necessary reaction protos, if mui, then mui ones.

Of course, there is still some includes, which not in "proto". But, including of proto are enough for most basic libs and functions. But sure, you will find in some examples, that together with protos, other ones are used as well. Like in our source you can find:

  1. #include <exec/types.h>
  2. #include <exec/ports.h>
  3. and so on

Through , most of the time including of protos are enough. You even can try to remove all that "strange non-protos" includes from our sources, and to see, if it will works without (pretty possible that will, but if not, then you can one by one uncomment back, and see, what was undefined and where, and what are necessary).

That "non proto" includes come from the old way of aos progamming. But on aos4 its more or less easy now, and all what you need its including of protos, just, when something undefined, do search over whole SDK on undefined words, and then include the include which you found.

Some note
As side note, i want to add, that i personally trying to use plain C/C++, posix and everything "cross-platform" when i can, to avoid aos only api. I.e. for AllocVec replacement i of course use stdlib.h funcs (which in end, anyway, use AllocVec, you just not see it, and your C code looks more cross-platform for everyone). Not cicle too much on os4 specific funcs, that will be necessary only when you will works with Reaction/Mui, or with Graphics, or with anything else what can't be done by plain C/C++ stuff.

Log in or register to post comments