LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 08-31-2007, 10:44 AM   #1
derrick_chi
LQ Newbie
 
Registered: Aug 2007
Posts: 4

Rep: Reputation: 0
Angry g++ function declaration and usage help!


Hello guys

I am new to this forum and to gcc/g++ and I need to know exactly how to declare a function in g++. I wrote a C++ program to calculate the GCD of two numbers, I've tested it and it works. I wanted to compile the program and target a mips processor so I issued the following command

"sde-g++ -c -mtune=r3k -T ph.ld -O2 GCD.cpp -o GCD.bin"

The program compiled fine, but would link because the linker for some reason did not reconize the iostream header file, no idea why?

So I used the -c option and like I said it compiled fine. However when I look over the disassembled list the assembly code is not quite correct, it looks as if the compiler placed the function "GCD" before the main() and before any initialization period. I read over the first few instructions and sure enough I was right because the function is placed before any initialization the program starts off within the function and can't get out its in an infinite loop and can't get out. I figured it must have something to do with how I am declaring the function and I wanted to ask you guys.

Someone help me please. The C++ code is pasted in below as well as the disassemble list.


#include "iostream"
#include "iomanip"
#include "math.h"


using namespace std;

unsigned int GCD_FUNCT( unsigned int, unsigned int );


int main() {

unsigned int ARRAY[32], GCD[16];
unsigned int Loop_Control_V, Reg1, Reg2, new_value;


for ( unsigned int i = 0; i < 31; ++ i ) {


new_value = i + ( 3 * (4) );

if ( new_value % 2 != 0 ) {

new_value = new_value * 4;
}

else{
new_value = new_value * 10;
}

ARRAY[i] = new_value;
}

Loop_Control_V = 0;

while ( Loop_Control_V < 30 ) {

if ( ARRAY[Loop_Control_V] > ARRAY[Loop_Control_V + 1] ) {


Reg1 = ARRAY[Loop_Control_V];
Reg2 = ARRAY[Loop_Control_V + 1];
}

else {
Reg1 = ARRAY[Loop_Control_V + 1];
Reg2 = ARRAY[Loop_Control_V];
}

GCD[Loop_Control_V] = GCD_FUNCT(Reg1,Reg2);
Loop_Control_V = Loop_Control_V + 1;

}

return 0;

}

unsigned int GCD_FUNCT( unsigned int REGa, unsigned int REGb) {

unsigned int temp1, temp2, GCD;

temp1 = REGa;
temp2 = REGb;

while ( temp1 != temp2 ) {

if ( temp1 > temp2 ) {

temp1 = temp1 - temp2;
}
else {
temp2 = temp2 - temp1;
}
}
GCD = temp1;
return GCD;
}


-- Disassemble list.

GCD.bin: file format elf32-tradbigmips

Disassembly of section .text:

00000000 <_Z9GCD_FUNCTjj>:
_Z9GCD_FUNCTjj():
0: 10850007 beq a0,a1,20 <_Z9GCD_FUNCTjj+0x20>
4: 00000000 nop
8: 00a4102b sltu v0,a1,a0
c: 10400006 beqz v0,28 <_Z9GCD_FUNCTjj+0x28>
10: 00000000 nop
14: 00852023 subu a0,a0,a1
18: 1485fffb bne a0,a1,8 <_Z9GCD_FUNCTjj+0x8>
1c: 00000000 nop
20: 03e00008 jr ra
24: 00801021 move v0,a0
28: 1000fff5 b 0 <_Z9GCD_FUNCTjj>
2c: 00a42823 subu a1,a1,a0

00000030 <main>:
main():
30: 27bdff20 addiu sp,sp,-224
34: 27a80010 addiu t0,sp,16
38: afbf00d8 sw ra,216(sp)
3c: afb100d4 sw s1,212(sp)
40: afb000d0 sw s0,208(sp)
44: 00002821 move a1,zero
48: 01003021 move a2,t0
4c: 24a2000c addiu v0,a1,12
50: 00021880 sll v1,v0,0x2
54: 24a50001 addiu a1,a1,1
58: 30440001 andi a0,v0,0x1
5c: 00621821 addu v1,v1,v0
60: 2ca7001f sltiu a3,a1,31
64: 14800002 bnez a0,70 <main+0x40>
68: 00021080 sll v0,v0,0x2
6c: 00031040 sll v0,v1,0x1
70: acc20000 sw v0,0(a2)
74: 14e0fff5 bnez a3,4c <main+0x1c>
78: 24c60004 addiu a2,a2,4
7c: 01008021 move s0,t0
80: 2411001d li s1,29
84: 8e060000 lw a2,0(s0)
88: 8e030004 lw v1,4(s0)
8c: 2631ffff addiu s1,s1,-1
90: 0066382b sltu a3,v1,a2
94: 00c02021 move a0,a2
98: 14e00003 bnez a3,a8 <main+0x78>
9c: 00602821 move a1,v1
a0: 00602021 move a0,v1
a4: 00c02821 move a1,a2
a8: 0c000000 jal 0 <_Z9GCD_FUNCTjj>
ac: 00000000 nop
b0: ae020080 sw v0,128(s0)
b4: 0621fff3 bgez s1,84 <main+0x54>
b8: 26100004 addiu s0,s0,4
bc: 8fbf00d8 lw ra,216(sp)
c0: 8fb100d4 lw s1,212(sp)
c4: 8fb000d0 lw s0,208(sp)
c8: 00001021 move v0,zero
cc: 03e00008 jr ra
d0: 27bd00e0 addiu sp,sp,224

000000d4 <_Z41__static_initialization_and_destruction_0ii>:
_Z41__static_initialization_and_destruction_0ii():
d4: 27bdffe0 addiu sp,sp,-32
d8: 38860001 xori a2,a0,0x1
dc: 38a5ffff xori a1,a1,0xffff
e0: afb00010 sw s0,16(sp)
e4: 2cc30001 sltiu v1,a2,1
e8: 2cb00001 sltiu s0,a1,1
ec: afb10014 sw s1,20(sp)
f0: 02031024 and v0,s0,v1
f4: 00808821 move s1,a0
f8: 3c040000 lui a0,0x0
fc: afbf0018 sw ra,24(sp)
100: 14400010 bnez v0,144 <_Z41__static_initialization_and_destruction_0ii+0x70>
104: 24840000 addiu a0,a0,0
108: 2e280001 sltiu t0,s1,1
10c: 3c090000 lui t1,0x0
110: 02083824 and a3,s0,t0
114: 14e00006 bnez a3,130 <_Z41__static_initialization_and_destruction_0ii+0x5c>
118: 25240000 addiu a0,t1,0
11c: 8fbf0018 lw ra,24(sp)
120: 8fb10014 lw s1,20(sp)
124: 8fb00010 lw s0,16(sp)
128: 03e00008 jr ra
12c: 27bd0020 addiu sp,sp,32
130: 8fbf0018 lw ra,24(sp)
134: 8fb10014 lw s1,20(sp)
138: 8fb00010 lw s0,16(sp)
13c: 08000000 j 0 <_Z9GCD_FUNCTjj>
140: 27bd0020 addiu sp,sp,32
144: 0c000000 jal 0 <_Z9GCD_FUNCTjj>
148: 00000000 nop
14c: 1000ffef b 10c <_Z41__static_initialization_and_destruction_0ii+0x38>
150: 2e280001 sltiu t0,s1,1

00000154 <_GLOBAL__I_main>:
_GLOBAL__I_main():
154: 24040001 li a0,1
158: 08000035 j d4 <_Z41__static_initialization_and_destruction_0ii>
15c: 3405ffff li a1,0xffff

00000160 <_GLOBAL__D_main>:
_GLOBAL__D_main():
160: 00002021 move a0,zero
164: 08000035 j d4 <_Z41__static_initialization_and_destruction_0ii>
168: 3405ffff li a1,0xffff
 
Old 08-31-2007, 12:18 PM   #2
perry
Member
 
Registered: Sep 2003
Location: USA & Canada
Distribution: Slackware 12.0
Posts: 978

Rep: Reputation: 30
Thumbs up Right Church, Wrong Pew: For C++ questions checkout C++.org

Here's a tutorial on how to include multiple header files!

C with Classes 101 - The Real World

In your case, have a header file of the same name as your source and place your prototype there. It's a good practise to get into as by default, the C compiler is giving you the default definition of any given function, something like int function();

Do this:
Code:
#ifndef _YOURFILENAME_H
#define _YOURFILENAME_H

unsigned int GCD_FUNCT( unsigned int, unsigned int );

#endif
And include that header where ever you use your function.
Code:
#include "iostream"
#include "iomanip"
#include "math.h"
#include "yourfilename.h"

using namespace std;

int main() {

unsigned int ARRAY[32], GCD[16];
unsigned int Loop_Control_V, Reg1, Reg2, new_value;

But do check out the tutorial, C & C++ will give you the firepower you need but hitting the ground running (like your doing) can cost you in learning curves. And it's a really good idea to place functions into their own source files if your project is going to grow any size at all. Or (at the very least) in this case, place you entire function before your main function. Your better off separating them into separate files in the long run!

Cheers

- Perry

Last edited by perry; 08-31-2007 at 12:27 PM.
 
Old 08-31-2007, 02:29 PM   #3
derrick_chi
LQ Newbie
 
Registered: Aug 2007
Posts: 4

Original Poster
Rep: Reputation: 0
Hi Thanks for the advice.

I did what you said and I defined another file and I put the function in that file and put the #include GCD_FUNCT.h statement in my code. However still when I compile the disassemble list looks the same, for some reason the function is being placed before initilization and the main which can not be correct. I've pasted in my files in below so you can take look. Thanks again.

sde-c++ -c -mtune=r3k -T ph.ld -O2 GCD.cpp -o GCD.bin
sde-objdump --disassemble --line-numbers --source GCD.bin > disassemble.list


----- .h File. -->

#ifndef _YOURFILENAME_H
#define _YOURFILENAME_H

unsigned int GCD_FUNCT( unsigned int REGa, unsigned int REGb) {

unsigned int temp1, temp2, GCD;

temp1 = REGa;
temp2 = REGb;

while ( temp1 != temp2 ) {

if ( temp1 > temp2 ) {

temp1 = temp1 - temp2;
}
else {
temp2 = temp2 - temp1;
}
}
GCD = temp1;
return GCD;
}

#endif


---- New C++ Code -->

#include "iostream"
#include "iomanip"
#include "math.h"
#include "GCD_FUNCT.h"

using namespace std;


int main() {

unsigned int ARRAY[32], GCD[16];
unsigned int Loop_Control_V, Reg1, Reg2, new_value;


for ( unsigned int i = 0; i < 31; ++ i ) {


new_value = i + ( 3 * (4) );

if ( new_value % 2 != 0 ) {

new_value = new_value * 4;
}

else{
new_value = new_value * 10;
}

ARRAY[i] = new_value;
}

Loop_Control_V = 0;

while ( Loop_Control_V < 30 ) {

if ( ARRAY[Loop_Control_V] > ARRAY[Loop_Control_V + 1] ) {


Reg1 = ARRAY[Loop_Control_V];
Reg2 = ARRAY[Loop_Control_V + 1];
}

else {
Reg1 = ARRAY[Loop_Control_V + 1];
Reg2 = ARRAY[Loop_Control_V];
}

GCD[Loop_Control_V] = GCD_FUNCT(Reg1,Reg2);
Loop_Control_V = Loop_Control_V + 1;

}

return 0;

}
 
Old 08-31-2007, 05:44 PM   #4
Tinkster
Moderator
 
Registered: Apr 2002
Location: earth
Distribution: slackware by choice, others too :} ... android.
Posts: 23,067
Blog Entries: 11

Rep: Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928
Not an answer to any of your questions, but a request: if
you post code, can you please put it in code tags?


Cheers,
Tink
 
Old 08-31-2007, 08:11 PM   #5
PTrenholme
Senior Member
 
Registered: Dec 2004
Location: Olympia, WA, USA
Distribution: Fedora, (K)Ubuntu
Posts: 4,187

Rep: Reputation: 354Reputation: 354Reputation: 354Reputation: 354
Consider asking the moderator to move this thread from "General" to "Programming." The "General" forum is for Linux questions not addressed in other fora.
 
Old 09-02-2007, 02:43 PM   #6
perry
Member
 
Registered: Sep 2003
Location: USA & Canada
Distribution: Slackware 12.0
Posts: 978

Rep: Reputation: 30
Thumbs up One more try!

This compiles just fine under Slackware's KDevelop IDE environment for C++ (G++):

Code:
/***************************************************************************
 *   Copyright (C) 2007 by derrick_chi, perry
 ***************************************************************************/

#ifndef _GCD_FUNCT_H
#define _GCD_FUNCT_H

unsigned int GCD_FUNCT( unsigned int REGa, unsigned int REGb);

#endif
 
Old 09-02-2007, 04:45 PM   #7
derrick_chi
LQ Newbie
 
Registered: Aug 2007
Posts: 4

Original Poster
Rep: Reputation: 0
Hi Perry

I want to thank you for taking the time to help me out and show me my errors in programming standards. However lets say I simplify the situation and get rid of the function and the header all together as I have done in the code below.


//#include "iso646.h"
#include "iostream"
#include "math.h"
#include "iomanip"

main() {

unsigned int ARRAY[32], GCD[16];
unsigned int Loop_Control_V, Reg1, Reg2, new_value, GCD_TEMP;


for ( unsigned int i = 0; i < 31; ++ i ) {

new_value = i + ( (3 * i) + 7 );
ARRAY[i] = new_value;

}

Loop_Control_V = 0;

while ( Loop_Control_V < 30 ) {

if ( ARRAY[Loop_Control_V] > ARRAY[Loop_Control_V + 1] ) {


Reg1 = ARRAY[Loop_Control_V];
Reg2 = ARRAY[Loop_Control_V + 1];
}

else {
Reg1 = ARRAY[Loop_Control_V + 1];
Reg2 = ARRAY[Loop_Control_V];
}


while ( Reg1 != Reg2 ) {

if ( Reg1 > Reg2 ) {

Reg1 = Reg1 - Reg2;
}
else {
Reg2 = Reg2 - Reg1;
}
}

GCD[Loop_Control_V] = Reg1;
Loop_Control_V = Loop_Control_V + 1;

}

}


Now the code above compiles fine and I can run it and get the results I want ( add a cout statement to it and see for yourself). The problem is that when I try do a sde-g++ compile or a mips-elf-g++ compile the machine code I get out isn't correct. I have pasted in the new disassemble list below for further explanation, ( jump past the section of code for the explanation of the problem).

gcd.bin: file format elf32-tradbigmips

Disassembly of section .text:

00000000 <main>:
main():
0: 27bdff40 addiu sp,sp,-192
4: 00002021 move a0,zero
8: 03a03021 move a2,sp
c: 00002821 move a1,zero
10: 00a43821 addu a3,a1,a0
14: 24840001 addiu a0,a0,1
18: 24e20007 addiu v0,a3,7
1c: 2c83001f sltiu v1,a0,31
20: acc20000 sw v0,0(a2)
24: 24a50003 addiu a1,a1,3
28: 1460fff9 bnez v1,10 <main+0x10>
2c: 24c60004 addiu a2,a2,4
30: 03a03821 move a3,sp
34: 2408001d li t0,29
38: 8ce60000 lw a2,0(a3)
3c: 8ce50004 lw a1,4(a3)
40: 00c02021 move a0,a2
44: 00a6482b sltu t1,a1,a2
48: 15200003 bnez t1,58 <main+0x58>
4c: 00a01821 move v1,a1
50: 00a02021 move a0,a1
54: 00c01821 move v1,a2
58: 10830006 beq a0,v1,74 <main+0x74>
5c: 0064282b sltu a1,v1,a0
60: 10a0000b beqz a1,90 <main+0x90>
64: 00000000 nop
68: 00832023 subu a0,a0,v1
6c: 1483fffc bne a0,v1,60 <main+0x60>
70: 0064282b sltu a1,v1,a0
74: 2508ffff addiu t0,t0,-1
78: ace40080 sw a0,128(a3)
7c: 0501ffee bgez t0,38 <main+0x38>
80: 24e70004 addiu a3,a3,4
84: 00001021 move v0,zero
88: 03e00008 jr ra
8c: 27bd00c0 addiu sp,sp,192
90: 1000fff1 b 58 <main+0x58>
94: 00641823 subu v1,v1,a0

00000098 <_Z41__static_initialization_and_destruction_0ii>:
_Z41__static_initialization_and_destruction_0ii():
98: 27bdffe0 addiu sp,sp,-32
9c: 38860001 xori a2,a0,0x1
a0: 38a5ffff xori a1,a1,0xffff
a4: afb00010 sw s0,16(sp)
a8: 2cc30001 sltiu v1,a2,1
ac: 2cb00001 sltiu s0,a1,1
b0: afb10014 sw s1,20(sp)
b4: 02031024 and v0,s0,v1
b8: 00808821 move s1,a0
bc: 3c040000 lui a0,0x0
c0: afbf0018 sw ra,24(sp)
c4: 14400010 bnez v0,108 <_Z41__static_initialization_and_destruction_0ii+0x70>
c8: 24840000 addiu a0,a0,0
cc: 2e280001 sltiu t0,s1,1
d0: 3c090000 lui t1,0x0
d4: 02083824 and a3,s0,t0
d8: 14e00006 bnez a3,f4 <_Z41__static_initialization_and_destruction_0ii+0x5c>
dc: 25240000 addiu a0,t1,0
e0: 8fbf0018 lw ra,24(sp)
e4: 8fb10014 lw s1,20(sp)
e8: 8fb00010 lw s0,16(sp)
ec: 03e00008 jr ra
f0: 27bd0020 addiu sp,sp,32
f4: 8fbf0018 lw ra,24(sp)
f8: 8fb10014 lw s1,20(sp)
fc: 8fb00010 lw s0,16(sp)
100: 08000000 j 0 <main>
104: 27bd0020 addiu sp,sp,32
108: 0c000000 jal 0 <main>
10c: 00000000 nop
110: 1000ffef b d0 <_Z41__static_initialization_and_destruction_0ii+0x38>
114: 2e280001 sltiu t0,s1,1

00000118 <_GLOBAL__I_main>:
_GLOBAL__I_main():
118: 24040001 li a0,1
11c: 08000026 j 98 <_Z41__static_initialization_and_destruction_0ii>
120: 3405ffff li a1,0xffff

00000124 <_GLOBAL__D_main>:
_GLOBAL__D_main():
124: 00002021 move a0,zero
128: 08000026 j 98 <_Z41__static_initialization_and_destruction_0ii>
12c: 3405ffff li a1,0xffff


OK here is the problem there is something wrong with the way the compiler is compiling the code because it is creating branches that I believe go to the wrong addresses. Lets look at the section of code below.

0: 27bdff40 addiu sp,sp,-192
4: 00002021 move a0,zero
8: 03a03021 move a2,sp
c: 00002821 move a1,zero
10: 00a43821 addu a3,a1,a0
14: 24840001 addiu a0,a0,1
18: 24e20007 addiu v0,a3,7
1c: 2c83001f sltiu v1,a0,31
20: acc20000 sw v0,0(a2)
24: 24a50003 addiu a1,a1,3
28: 1460fff9 bnez v1,10 <main+0x10>


This section of code is basically the first loop in the orginal C++ program where Array[]'s values are being calculated and placed into the array, in the case of the processor the values should be placed on the stack, and the stack pointer should be incremented.

for ( unsigned int i = 0; i < 31; ++ i ) {

new_value = i + ( (3 * i) + 7 );
ARRAY[i] = new_value;

}

OK the code on lines 0-1c is setting up the stack pointer. The code in lines 10 - 20 are calculating the values for Array.

(new_value = i + ( (3 * i) + 7 ),

OK the code on line 20 is storing the calculated value onto the stack at a2(which holds the pointer to the stack) + 0, and once the value is stored the code checks to see if 31 "new_values" have been stored and if not it branches back to line 10 and begins to calculate the next "new_value".

NOW the problems is that the location of the stack pointer is never incremented, or decremented anywhere in this section of code, as a matter of fact the machine code ( acc20000 sw v0,0(a2) )
points that out clearly, its adding 0 to the location of the stack and therefore the new_values are over written by the next value being calculated and added to the stack "at the very same spot" that the last values were added. Do you see that?


I don't know how the compiler generated this type of machine code because I can't work so there must be something that I am doing wrong, any help you can provide I do greatly apprieciate, and you help so far has been great! Fill free to post this where ever you like.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
unknown C++ function declaration syntax kpachopoulos Programming 1 08-29-2007 03:43 PM
Function Declaration in C frankie_DJ Programming 5 10-11-2006 12:44 PM
C: Function declaration woes websinger Programming 4 08-08-2006 02:56 PM
Arguments in PHP function declaration Parksy Programming 5 07-04-2004 04:22 PM
Problem with function declaration Linh Programming 3 04-26-2004 04:58 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 01:48 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration