Here is a generic solution; it is standard conforming as long as T is some variant of int ( signed, short, long...).
template <typename T, unsigned B>
inline T sign_extend(const T x)
{
struct {T x:B;} s;
return s.x = x;
}
So for 10-bits extended to 16-bits:
int result = sign_extend< signed int ,10 >(x);