If g() is a "regular" function, as you call it, then in the compiled code for f(), you will see the compiler generate code to push the parameters of g() onto the stack, then emit a CALL instruction to jump to the function. Inside g(), you'll see the compiler emit instructions to set up the stack frame. At the end of g(), you'll see the compiler emit instructions to tear down the stack frame and RET to where it was called from.
If g() is an "inline" function, then the compiler will take the implementation of g() and insert it directly into the compiled code for f(), so you won't see any of the instructions I mentioned above.
Advantages: when g() is very small, the overhead of calling the function can be equal to or greater than the amount of "real" work done by g(). You can speed up your program by inlining g(), however you won't see any difference unless you are calling g() a LOT.
Disadvantages: Instead of g() being compiled once, it is now compiled each time you call it. This results in a larger executable since the actual instructions of g() are now duplicated N times. There can also be performance penalties inside f() for inlining because it makes f() contain more code, thus the compiler may not be able to optimize it as much. Another disadvantage is that the contents of g() must be seen by the compiler when f() is called. In practice, this means either that g() is implemented in the same .cpp file as f(), or g() is implemented in a header file.