There's something of a difference between what you can do and what you should do.
You can do what you show in your question. At least in my opinion, what you should do (since you're using C++) is use an RAII wrapper to automate getting your LeaveCriticalSection calls to match your EnterCriticalSection calls.
class crit_sect {
CRITICAL_SECTION cs;
void lock() { EnterCriticalSection(&cs); }
void unlock() { LeaveCriticalSection(&cs); }
friend class lock;
crit_sect(crit_sect const &); /* = delete; */
crit_sect &operator=(crit_sect const &other); /* = delete; */
public:
crit_sect() { InitializeCriticalSection(&cs); }
~crit_sect() { DeleteCriticalSection(&cs); }
};
class lock {
crit_sect &cs;
public:
lock(crit_sect &c) : cs(c) { cs.lock(); }
~lock() { cs.unlock(); }
};
Using these, you'd have something like:
if (whatever) {
lock list_lock(g_List);
lock var_lock(g_Variable);
// ...
}
...and when execution leaves the scope in which the two locks were defined, the destructors will execute, automatically unlocking the critical sections. This is handy and convenient; if you're using exceptions, it becomes even more important, because it means if you exit the scope via an exception instead of via normal execution, the critical sections will still be unlocked.