if I compile code on a 64 bit PC, will it work on the Pi?
No -- as per other answers, C++ is a purely compiled language, meaning it goes straight from source to machine code, which is architecture specific. Or it might be more accurate to say once compiled into an executable that executable is stored as machine code; when it is compiled I believe it generally passes through intermediate steps, the most significant of which would be C -> assembly (which is architecture specific) -> machine code. Assembly is more-or-less a human readable form of machine code (but can't be directly executed).
Sort of like how Java runs in everything
This is because java is compiled to bytecode (e.g., .class
files), which is interpreter specific. The interpreters themselves are executable machine code and as such not portable; i.e., the JRE from an x86_64 PC could not be used on a Pi. However, java code written and compiled on the PC could be run on the Pi by its java interpreter.
So compiled java bytecode is executed by an interpreter which is executed by the CPU, which is why the compiled bytecode is portable. Machine code is executed directly by the CPU, and as such must be created specifically for the style of CPU it is to be executed on.
If I write code on a PC, can it compile on a Pi
Yes, but there is a caveat to this.
C++ is a very portable language, but as just explained, it must be compiled into a very unportable form before it can be useful. The caveat is that there are some things which are not standardized in C or C++, and these are "platform dependence" issues. In this context "platform" refers more or less to two fundamental elements of the operating system, the kernel and the native C library, upon which the C++ library depends. The relationship between these two things is very intimate due to the nature of system calls. There are a wide range of things programs are dependent on the kernel to do for them; the primary role of the kernel is to coordinate such activities. These are things which involve peripheral hardware, i.e., anything beyond the CPU and main memory (including the keyboard, the display, storage, etc). Further, on contemporary multi-tasking OS's the kernel also controls when and for how long process code gets to run on the CPU. So again, a very high degree of intimate cooperation is involved.
There are at least two significant, fundamental areas that "standard C" does not cover here:
The former is largely made up for by the fact that there is standardized access to files via the file stream interface. However, note this does not include reading directories!
The second one, networking, simply isn't covered at all, although some aspects of actual networking may use stream interfaces that are identical to those used to access files. However, neither standard C nor C++ includes basic functions required to, e.g., create/open a network socket and make an inet connection.
Those things are dealt with in platform specific libraries, meaning they vary not from processor to processor but from operating system to operating system, or categories/families of such. The operating system predominantly used on the Pi is GNU/Linux (where the kernel is linux, and the native libraries are from GNU); Raspbian is a form of this (sometimes different forms of GNU/Linux are referred to as individual operating systems, e.g., Raspbian, Ubuntu, etc., but in this context they are all identical to one another).
GNU/Linux is regarded as mostly POSIX compliant. This is the largest group of operating systems in the computing world, and includes various direct UNIX decedents such as Solaris, early offshoots such as BSD, later offshoots such as linux, and OSX. POSIX does include standardization for networking and filesystem access in C, so if you are writing networking code for use on Raspbian or linux generally it can be done following POSIX standards.
However, the operating system used predominantly on PCs, Microsoft Windows, is not a POSIX compliant operating system and has its own customized libraries for things such as networking.
So that's the one thing to beware of: If you are writing networking code in C++ on a Windows PC, it will not be portable to a Linux powered Pi. There are cross-platform networking libraries available for C++, however (I believe boost should have this well covered), which will allow you to get around that. On the other hand, if you are using Linux on your PC and don't plan to port your code to Windows then you can use standard linux/POSIX methodologies and it will compile and run fine on any linux based device regardless of architecture.
Well, ideally it will. Porting code from one architecture to another is a classic and I think commonplace way to discover bugs in your code that you did not know existed. This is because a particular compiler on a particular platform and architecture may, e.g., arrange things in a way that is forgiving of a small buffer overrun. This is a sort of luck which can be become bad when that code is compiled elsewhere, and by coincidence the arrangement is not so forgiving and suddenly something that has run fine for years blows up in your face.
Fixing those things is the same as fixing them when they don't work in the first place, although it may be particularly tedious and irritating if it is something large and complex which was built up over time and the flaw was incorporated early on. Of course, if it is all appropriately compartmentalized and you have basic tests for the components, you can hopefully pin the issue down using those tests, and once the code is fixed it will run fine in both contexts.