if I do:
int x = 4;
pow(2, x);
Is that really that much less efficient than just doing:
1 << 4
?
Yes. Though by how much I can't say. The easiest way to determine that is to benchmark it.
The pow function uses doubles...  At least, if it conforms to the C standard.  Even if that function used bitshift when it sees a base of 2, there would still be testing and branching to reach that conclusion, by which time your simple bitshift would be completed.  And we haven't even considered the overhead of a function call yet.
For equivalency, I assume you meant to use 1 << x instead of 1 << 4.
Perhaps a compiler could optimize both of these, but it's far less likely to optimize a call to pow.  If you need the fastest way to compute a power of 2, do it with shifting.
Update... Since I mentioned it's easy to benchmark, I decided to do just that. I happen to have Windows and Visual C++ handy so I used that. Results will vary. My program:
#include 
#include 
#include 
#include 
LARGE_INTEGER liFreq, liStart, liStop;
inline void StartTimer()
{
    QueryPerformanceCounter(&liStart);
}
inline double ReportTimer()
{
    QueryPerformanceCounter(&liStop);
    double milli = 1000.0 * double(liStop.QuadPart - liStart.QuadPart) / double(liFreq.QuadPart);
    printf( "%.3f ms\n", milli );
    return milli;
}
int main()
{    
    QueryPerformanceFrequency(&liFreq);
    const size_t nTests = 10000000;
    int x = 4;
    int sumPow = 0;
    int sumShift = 0;
    double powTime, shiftTime;
    // Make an array of random exponents to use in tests.
    const size_t nExp = 10000;
    int e[nExp];
    srand( (unsigned int)time(NULL) );
    for( int i = 0; i < nExp; i++ ) e[i] = rand() % 31;
    // Test power.
    StartTimer();
    for( size_t i = 0; i < nTests; i++ )
    {
        int y = (int)pow(2, (double)e[i%nExp]);
        sumPow += y;
    }
    powTime = ReportTimer();
    // Test shifting.
    StartTimer();
    for( size_t i = 0; i < nTests; i++ )
    {
        int y = 1 << e[i%nExp];
        sumShift += y;
    }
    shiftTime = ReportTimer();
    // The compiler shouldn't optimize out our loops if we need to display a result.
    printf( "Sum power: %d\n", sumPow );
    printf( "Sum shift: %d\n", sumShift );
    printf( "Time ratio of pow versus shift: %.2f\n", powTime / shiftTime );
    system("pause");
    return 0;
}
    My output:
379.466 ms
15.862 ms
Sum power: 157650768
Sum shift: 157650768
Time ratio of pow versus shift: 23.92