Yes, it is standard behavior and will work in all C compilers.
Function calls are actually always made through a pointer to function:
6.5.22 "Function calls":
The expression that denotes the called function (footnote 77) shall have type pointer to function returning void or returning an object type other than an array type
As footnote 77 indicates, a 'normal' function identifier is actually converted to a pointer-to-function when a function call is expression is used:
Footnote 77:
Most often, this is the result of converting an identifier that is a function designator.
Interestingly, dereferencing a function pointer (or a function designator converted to a function pointer) yields a function designator for the function, which will be converted back to a function pointer for the function call expression. So you can dereference the function pointer (or a normal function name), but don't have to.
6.5.3.2/4 "Address and indirection operators":
The unary * operator denotes indirection. If the operand points to a function, the result is a function designator
So as far as the standard is concerned, for your examples:
(*fptr)(1,2);
fptr(1,2);
The second isn't really a shorthand - it's what the compiler expects. Actually, the first example is really just a more verbose way of saying the same thing as the second. But some people might prefer the first form as it makes it more clear that a pointer is being used. There should be absolutely no difference in the generated code.
Another consequence of the standard's wording is that you can just as well dereference a normal function name:
func(1,2);
(*func)(1,2); // equivalent to the above
Not that there's really any defensible point to doing that that I can think of.