Estado global no CRT
Algumas funções no UCRT (Runtime Universal C) usam o estado global. Por exemplo, setlocale()
define a localidade para todo o programa, o que afeta os separadores de dígito, a página de código de texto e assim por diante.
O estado global do UCRT não é compartilhado entre aplicativos e o sistema operacional. Por exemplo, se o aplicativo chamar setlocale()
, ele não afetará a localidade de nenhum componente do sistema operacional que use o tempo de execução do C ou o contrário.
Versões de funções do CRT específicas do sistema operacional
No UCRT, as funções que interagem com o estado global têm uma função "gêmea", prefixada com _o_
. Por exemplo:
setlocale()
afeta o estado global específico do aplicativo._o_setlocale()
afeta o estado global compartilhado por todos os componentes do sistema operacional, mas não por aplicativos.
A única diferença entre essas funções "gêmeas" é que, quando elas leem/gravam o estado global do CRT, as versões específicas do sistema operacional (ou seja, as versões que começam com _o_
) usam a cópia do estado global do sistema operacional em vez da cópia do estado global do aplicativo.
As versões específicas do sistema operacional dessas funções estão na ucrt.osmode.lib
. Por exemplo, a versão do setlocale()
específica do sistema operacional é _o_setlocale()
Há duas maneiras de isolar o estado do componente do CRT do estado de um aplicativo do CRT:
- Vincule o componente estaticamente usando opções do compilador
/MT
(lançamento) ou/MTd
(depuração). Para obter detalhes, confira /MD, /MT, /LD. A vinculação estática pode aumentar consideravelmente o tamanho do binário. - A partir do Windows 10 versão 2004, vincule dinamicamente ao CRT, mas chame as exportações do modo do sistema operacional (as funções que começam com o). Para chamar as exportações do modo do sistema operacional, vincule estaticamente como antes, mas ignore o UCRT estático usando a opção do vinculador
/NODEFAULTLIB:libucrt.lib
(lançamento) ou/NODEFAULTLIB:libucrtd.lib
(depuração). E adicioneucrt.osmode.lib
à entrada do vinculador. Consulte/NODEFAULTLIB
(Ignorar bibliotecas) para obter detalhes.
Observação
No código-fonte, escreva setlocale()
, não _o_setlocale()
. Quando você vincular no ucrt.osmode.lib
, o vinculador substituirá automaticamente a versão específica do sistema operacional da função. Ou seja, setlocale()
será substituído por _o_setlocale()
.
A vinculação no ucrt.osmode.lib
desabilita algumas chamadas ao UCRT que só estão disponíveis no modo de aplicativo. A tentativa de chamar essas funções resultará em um erro de link.
Estado global afetado pela separação de aplicativo/sistema operacional
O estado global afetado pela separação do aplicativo e do estado do sistema operacional inclui:
- Dados de localidade
- Manipuladores de sinal definidos por
signal
- Rotinas de encerramento definidas por
terminate
errno
e_doserrno
- Estado de geração de números aleatórios usado por
rand
esrand
- Funções que retornam um buffer que o usuário não precisa liberar:
strtok
,wcstok
,_mbstok
Tmpnam
,_wtmpnam
asctime
,_wasctime
gmtime
,_gmtime32
,_gmtime64
_fcvt
_ecvt
strerror
,_strerror
,_wcserror
,__wcserror
- O buffer usado por
_putch
,_putwch
_set_invalid_parameter_handler
,_set_thread_local_invalid_parameter_handler
_set_new_handler
e_set_new_mode
fmode
- Informações de fuso horário