I think we've gone off-base with discussing how a compiler may or may not inline a function or how a compiler translates source code into machine language. The fact of the matter is that all of the structured statements (if, for, while, switch, etc) can be compiled down to "jump" or "branch" instructions, which are more or less equivalent to C's "goto" statement.
The other fact is that it doesn't really matter how C statements are compiled into machine code (unless you're optimizing your code, which is unnecessary for probably 99% of the time). What does matter is whether the use of goto makes the source code more readable and easier to follow and understand. If it makes source code easier to understand, use it; otherwise, don't. Source code should still be written for humans to read.
That said, I use goto only for exception handling, just as it's used in the Linux kernel (see Codeplug's comment in particular). I find that it's a lightweight method to handle error conditions (another way is to use setjmp/longjmp, but that is not so lightweight). In a language with native support for exceptions (like C++), I argue that goto is never necessary nor useful.
The main point I was making is that how C statements get melted down into machine instructions should not influence a programmer's choice in which statements or constructions to use, but rather a programmer should use whatever is easiest to understand. So I think we shouldn't be discussing the low-level stuff when deciding whether to use goto or some other construct.
By the way, TheBigH is almost correct about function calls being goto by another name (again, at the machine level). A function call is basically saving the current program location, or rather the following program location (the "return address"), and then jumping/branching to another location (the start of the function). Most processors do have special instructions to do both of these steps in a single instruction (like "call" on x86), and there has to be a way to pass arguments to the function and to retrieve the return value from the function (which are really just operations done before and after the "call" instruction), but it's still a jump/goto. Likewise, returning from a function is basically jumping (goto'ing) the saved program location. (Some old BASIC interpreters made the similarity between goto and function calls more obvious: the GOTO and GOSUB commands were the same--they both jumped to a line number--except that GOSUB would save the next line number to a stack before jumping.)
Your code will always be executed somewhere so you need to be aware of the limitations and benefits of the architecture it is deployed on. Theoretically, C is a high level language, at least by comparison to assembly, and you will find C code deployed on a variety of architectures with a variety of implementations that squeeze out every possible optimisation on that architecture.
No, optimisations that are aware of hardware limmits are not only for embedded programming. For example, it is common for high level programmers to optimise data access into 64 byte snippets for cacheing purposes. But the use of goto is not for optimisation.
Secondly, don't think you know anything about how I code, this is really just another ungrounded assumption.
you have misinterpreted my words, possibly deliberately.
my statement was that a programmer does not need to understand the details of the architecture to write C code. I did not at any time suggest that one should always ignore said details. I have not in any way said that code "magically floats in the air." My statement was that pure standard-compliant C code will compile and run on any platform that has a standard-compliant compiler environment. I don't know where you got the part about magically floating in the air. you're just putting words in my mouth.