I've started working with structs and am having difficulty getting my head around splitting them up into .h and .cpp files. I understand that .h are usually used for declarations, whereas .cpp are used for definitions. The issue I've run into is I can't work out how to define the standard variables for two separate structs when these variables have the same names.
I think my issue is that the three variables for each struct are not being associated inside them (error 1). I tried taking these variables out of the .cpp files but then I get the issue that the variables within void Reset()
were not declared within that scope.
What I am trying to achieve is having these variables within the struct with default values. The Reset()
function, when called, will reset these values.
I'm running from Konsole with this: g++ -o main cpu.cpp main.cpp && ./main
/usr/bin/ld: /tmp/ccwb32XV.o:(.bss+0x3): multiple definition of `PS'; /tmp/ccY9ydGx.o:(.data+0x3): first defined here
collect2: error: ld returned 1 exit status
cpu.cpp:9:5: error: ‘PC’ was not declared in this scope
9 | PC = 0xFFFC;
#include <cstdint>
struct CPU
{
std::uint16_t PC;
std::uint8_t SP;
std::uint8_t PS;
void Reset();
};
#include "cpu.h"
std::uint16_t PC = 0x1234;
std::uint8_t SP = 0x56;
std::uint8_t PS = 0b10101010;
void Reset()
{
PC = 0xFFFC;
SP = 0xFF;
PS = 0b00010000;
}
#include <cstdint>
struct PPU
{
std::uint16_t X;
std::uint8_t Y;
std::uint8_t PS;
void Reset();
void PrintSomething();
};
#include <cstdint>
#include <iostream>
#include "ppu.h"
std::uint16_t X = 0x1010;
std::uint8_t Y = 0x99;
std::uint8_t PS = 0b11001100;
void Reset()
{
PC = 0xAABC;
SP = 0x02;
PS = 0b00000110;
}
void PrintSomething()
{
std::cout << "Printing something!" << std::endl;
}
#include <iostream>
#include "cpu.h"
#include "ppu.h"
int main()
{
CPU cpu;
PPU ppu;
std::cout << "Hello, World!" << std::endl;
}
You are setting up your .cpp
files the wrong way. You do not need to define non-static data members separately at all (only static data members, which you don't have). You do need to define member functions, like Reset()
, but to do that correctly you need to fully qualify the struct name in the definition.
Also, don't forget to put header guards in each .h
file. And, you need to compile and link every .cpp
file.
Try this instead:
g++ -o main cpu.cpp ppu.cpp main.cpp && ./main
cpu.h
#ifndef CPU_H
#define CPU_H
#include <cstdint>
struct CPU
{
std::uint16_t PC = 0x1234;
std::uint8_t SP = 0x56;
std::uint8_t PS = 0b10101010;
void Reset();
};
#endif
cpu.cpp
#include "cpu.h"
void CPU::Reset()
{
PC = 0xFFFC;
SP = 0xFF;
PS = 0b00010000;
}
ppu.h
#ifndef PPU_H
#define PPU_H
#include <cstdint>
struct PPU
{
std::uint16_t X = 0x1010;
std::uint8_t Y = 0x99;
std::uint8_t PS = 0b11001100;
void Reset();
void PrintSomething();
};
#endif
ppu.cpp
#include <iostream>
#include "ppu.h"
void PPU::Reset()
{
X = 0x1010;
Y = 0x99;
PS = 0b11001100;
}
void PPU::PrintSomething()
{
std::cout << "Printing something!" << std::endl;
}
main.cpp
#include <iostream>
#include "cpu.h"
#include "ppu.h"
int main()
{
CPU cpu;
PPU ppu;
std::cout << "Hello, World!" << std::endl;
}