C++ functions can't access variables outside their scope?
C++ functions can't access variables outside their scope?
I'm sorry to ask something so weird and trivial, but I couldn't find anything when searching for it anywhere. I've hit a brick wall in development. I've got some printing code here, in C++. Everything's in a class, as they all keep track of the screen using some class variables. Now, I got a problem. If I make a new instance of this class, it resets and overwrites what the old one wrote (like if I'm passing control to another function), because the constructor initiates everythign to 0 of course. I can't just make a new instance in the global scope, because functions seem to ignore it. It compiles (and boots I think, it won't print but Qemu doesn't reset). Only thing is, the calls to the class' methods don't actually get called, it just sits there with a blinking cursor. Works fine if I make a new instance within the function, but outside doesn't work. Same thing if I make a struct in global with the screen information, the printing functions themselves can't get access to it (which I only theorize). And even weirder, if I ignore structs all together and make the screen information simple global integers, not even a cursor shows up, just a solid black screen. It's got nothing to do with them being in a class, I tried making them normal functions and the same thing happened. This problem persists in both GCC and Clang, but I never heard of it before. Am I doing something wrong, or is this a part of programming on the metal? I've seen other people's code and it looks like they can use global variables, so I'm pretty confused.
Oh, and just testing putting an integrer in global, looks like functions in the main file can reach it. Main doesn't want to reach the class instance in global, and the printing code doesn't want to reach a few global ints. This sure is a perplexing.
Thank you for any responces, I'm very stuck and confused here.
Oh, and just testing putting an integrer in global, looks like functions in the main file can reach it. Main doesn't want to reach the class instance in global, and the printing code doesn't want to reach a few global ints. This sure is a perplexing.
Thank you for any responces, I'm very stuck and confused here.
Re: C++ functions can't access variables outside their scope
You'll have to share some code, perhaps, to demonstrate this is an actual problem. Until then, I think the problem is that you don't know C++well enough.
Re: C++ functions can't access variables outside their scope
@iansjack I've attempted to make everything static, it didn't work out. I've attempted a lot of different configurations of this code, I can't win :[
@sortie I will admit I'm no C++ guru, but I would have at least expected spawning a class in the global scope would work, since I've done that before in applications programming.
Here's the header and code: http://pastebin.com/JAAP39F7, http://pastebin.com/r6fSyGZz.
I'll admit, there are some things about OS development I do not yet have a grasp on, such as linking or using a debugger. I was going to learn these in detail, but I was going a top-down approach where I just get something up that can print, then learn about everything and toy with it.
I was mainly just asking if using the global scope is even possible or not, because if it is, then something on my side is terribly broken. Sorry for wasting your time otherwise.
@sortie I will admit I'm no C++ guru, but I would have at least expected spawning a class in the global scope would work, since I've done that before in applications programming.
Here's the header and code: http://pastebin.com/JAAP39F7, http://pastebin.com/r6fSyGZz.
I'll admit, there are some things about OS development I do not yet have a grasp on, such as linking or using a debugger. I was going to learn these in detail, but I was going a top-down approach where I just get something up that can print, then learn about everything and toy with it.
I was mainly just asking if using the global scope is even possible or not, because if it is, then something on my side is terribly broken. Sorry for wasting your time otherwise.
Re: C++ functions can't access variables outside their scope
That code doesn't show a global variable of class vga anywhere? I'd like both the class and where it is used.
Re: C++ functions can't access variables outside their scope
haha, oops. Here it is: http://pastebin.com/w02EDA0M. Like I said, just calling it, nothing fancy
Edit: kernel.hxx is empty if you were wondering.
Edit: kernel.hxx is empty if you were wondering.
Last edited by konacake on Sat Nov 15, 2014 2:28 pm, edited 1 time in total.
Re: C++ functions can't access variables outside their scope
You are using global constructors without calling them!konacake wrote:I'm sorry to ask something so weird and trivial, but I couldn't find anything when searching for it anywhere. I've hit a brick wall in development. I've got some printing code here, in C++. Everything's in a class, as they all keep track of the screen using some class variables. Now, I got a problem. If I make a new instance of this class, it resets and overwrites what the old one wrote (like if I'm passing control to another function), because the constructor initiates everythign to 0 of course. I can't just make a new instance in the global scope, because functions seem to ignore it. It compiles (and boots I think, it won't print but Qemu doesn't reset). Only thing is, the calls to the class' methods don't actually get called, it just sits there with a blinking cursor. Works fine if I make a new instance within the function, but outside doesn't work. Same thing if I make a struct in global with the screen information, the printing functions themselves can't get access to it (which I only theorize). And even weirder, if I ignore structs all together and make the screen information simple global integers, not even a cursor shows up, just a solid black screen. It's got nothing to do with them being in a class, I tried making them normal functions and the same thing happened. This problem persists in both GCC and Clang, but I never heard of it before. Am I doing something wrong, or is this a part of programming on the metal? I've seen other people's code and it looks like they can use global variables, so I'm pretty confused.
Oh, and just testing putting an integrer in global, looks like functions in the main file can reach it. Main doesn't want to reach the class instance in global, and the printing code doesn't want to reach a few global ints. This sure is a perplexing.
Thank you for any responces, I'm very stuck and confused here.
That's your problem. If you're using them, please see this wiki article. What happens is simple, you're not calling them. When you initialize an object globally, crti.o, crtbegin.o, crtend.o, and crtn.o altogether form two functions: _init() and _fini(). The program's entry point, crt0.o, is responsible for calling them, altogether with the C library's initialization code and your main() function. Once you create a userspace program that uses them, the linker automatically links your program with those 5 object files, and the C library and dependencies of course. But, in kernel land, this doesn't happens automatically. GCC/Clang is pasting the needed tables to use them, but you're not using them. And viola! Your buffer member in your vga class never gets the value 0xB8000, it could be 0x0000 or 0x1234, or anything else. In any case, you're writing to somewhere you shouldn't. You could be overwritting the BIOS Data Area! Simply follow the steps in the link and everything should work.
Happy New Code!
Hello World in Brainfuck :[/size]
Hello World in Brainfuck :
Code: Select all
++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
Re: C++ functions can't access variables outside their scope
wow Kemy, thank you! I knew it was something to do with the linker. I'm gonna read up on that page hard. Again, thank you, that was a pitfall I was not informed of.
Re: C++ functions can't access variables outside their scope
Well, I've hit another wall. I think it's similar enough to this problem, so I'll post it in this thread. I've done as much research as I know how to do so I could fix this myself, but I'm stuck.
I'm using a 64-bit Ubuntu, so naturally my crtbegin.o and crtend.o are 64-bit. My kernel was originally 32-bit, so I switched it over to 64-bit using this tutorial. As much as I've tried to fix it, I keep getting the "relocation truncated to fit" error. My makefile output.
I've tried different compiler/nasm/ld flags and looking at other OS's boot/make files, but I'm stumped. This is my (very messy) makefile and This is my crti.asm and crtn.asm, appended into one file for viewing convienence.
I'm sorry to bother you guys for wisdom again, but I don't know what I'm doing (kinda why I want to learn)
I'm using a 64-bit Ubuntu, so naturally my crtbegin.o and crtend.o are 64-bit. My kernel was originally 32-bit, so I switched it over to 64-bit using this tutorial. As much as I've tried to fix it, I keep getting the "relocation truncated to fit" error. My makefile output.
I've tried different compiler/nasm/ld flags and looking at other OS's boot/make files, but I'm stumped. This is my (very messy) makefile and This is my crti.asm and crtn.asm, appended into one file for viewing convienence.
I'm sorry to bother you guys for wisdom again, but I don't know what I'm doing (kinda why I want to learn)
-
- Member
- Posts: 307
- Joined: Wed Oct 30, 2013 1:57 pm
- Libera.chat IRC: no92
- Location: Germany
- Contact:
Re: C++ functions can't access variables outside their scope
Are you using a cross-compiler? If not, build one first.
Re: C++ functions can't access variables outside their scope
Did you read this: GCC Cross-Compiler?
Although that's the recommended article, you can also be interested in: LLVM Cross-Compiler
You're not using a cross-compiler, which is essential for OSDev'ing. The correct crt*.o family is the one provided with your cross-compiler. NEVER, NEVER adapt your project to your system. It won't either work or make sense. Anyway, in x64 there're some pitfalls you should be careful of. If you really like it, there's no problem. Lots of people here do it that way .
Although that's the recommended article, you can also be interested in: LLVM Cross-Compiler
You're not using a cross-compiler, which is essential for OSDev'ing. The correct crt*.o family is the one provided with your cross-compiler. NEVER, NEVER adapt your project to your system. It won't either work or make sense. Anyway, in x64 there're some pitfalls you should be careful of. If you really like it, there's no problem. Lots of people here do it that way .
Happy New Code!
Hello World in Brainfuck :[/size]
Hello World in Brainfuck :
Code: Select all
++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
Re: C++ functions can't access variables outside their scope
Oh, thanks guys! I didn't build one because I'm using Clang, so I believed I didn't need one. But thinking about it now I probably do need GCC's libraries since Clang goes and uses them anyway. I'll try building one! I sure feel silly for not thinking of that
Re: C++ functions can't access variables outside their scope
Somehow, things still aren't working for me
I've downloaded the pre-built x86-targeting and x86_64-targeting cross-compilers from that wiki page (the 64-bit linux versions). I'm not too sure about the 64-bit one actually working or if I have to compile my own, or if it's my 64-bit code (I'm getting the "relocation truncated to fit" error again with it), but right now I'm more concerned on getting something working so I know what is and isn't working elsewhere. The pre-built x86-targeting cross-compiler works, and it makes a bootable image, but somehow the C++ side still can't actually see the global scope. It works if I make a local instance of a class, but a global instance doesn't get called. I'm very worried it's my crti.asm and crtn.asm files, but I'm also worried it's somehow the pre-built cross-compiler even though it works. Does anyone have any idea what I'm doing wrong now?
My crti.asm and crtn.asm files.
My Makefile (I'm only calling kernel32 of course, the 64-bit compiler is commented out since I haven't really learned how to make a good makefile yet)
I'm also using the code from this tutorial (everything except main.c) for booting the 32-bit kernel, I'm not sure how relevant this is.
Edit: Okay, I'm dumb. I'm not calling _init or _fini
However, I don't know where or how to call them. I'm not very versed in x86 Assembly, so my knowledge of it is second-hand at best. I've tried calling _init a line before calling kmain in start.asm, but that causes qemu to crash saying it tried to modify outside of RAM and ROM. So, again, I'm afraid my crti.asm is screwed up.
Edit2: Nevermind I fixed it. That's what I get for getting comfy and asking questions before giving it the old collage try. Thanks again guys, you were a tremendous help and I wouldn't have been able to do this without you.
Edit3: I should probably at least say what I did though for anyone else who finds this thread. I just put "extern "C" void _init();" at the top of my main file and then called _init() after initalizing GDT and the gang, and finally in my start.asm I put [extern _init] (for NASM, not sure what it is in GAS).
I've downloaded the pre-built x86-targeting and x86_64-targeting cross-compilers from that wiki page (the 64-bit linux versions). I'm not too sure about the 64-bit one actually working or if I have to compile my own, or if it's my 64-bit code (I'm getting the "relocation truncated to fit" error again with it), but right now I'm more concerned on getting something working so I know what is and isn't working elsewhere. The pre-built x86-targeting cross-compiler works, and it makes a bootable image, but somehow the C++ side still can't actually see the global scope. It works if I make a local instance of a class, but a global instance doesn't get called. I'm very worried it's my crti.asm and crtn.asm files, but I'm also worried it's somehow the pre-built cross-compiler even though it works. Does anyone have any idea what I'm doing wrong now?
My crti.asm and crtn.asm files.
My Makefile (I'm only calling kernel32 of course, the 64-bit compiler is commented out since I haven't really learned how to make a good makefile yet)
I'm also using the code from this tutorial (everything except main.c) for booting the 32-bit kernel, I'm not sure how relevant this is.
Edit: Okay, I'm dumb. I'm not calling _init or _fini
However, I don't know where or how to call them. I'm not very versed in x86 Assembly, so my knowledge of it is second-hand at best. I've tried calling _init a line before calling kmain in start.asm, but that causes qemu to crash saying it tried to modify outside of RAM and ROM. So, again, I'm afraid my crti.asm is screwed up.
Edit2: Nevermind I fixed it. That's what I get for getting comfy and asking questions before giving it the old collage try. Thanks again guys, you were a tremendous help and I wouldn't have been able to do this without you.
Edit3: I should probably at least say what I did though for anyone else who finds this thread. I just put "extern "C" void _init();" at the top of my main file and then called _init() after initalizing GDT and the gang, and finally in my start.asm I put [extern _init] (for NASM, not sure what it is in GAS).