| FAQ Lite | ||||||||||||||||||||
| Compiladores | ||||||||||||||||||||
|
||||||||||||||||||||
| [ 33.1 ] Onde eu posso conseguir mais informações sobre o uso de MFC e Visual C++? |
| Em MFC/Visual C++ FAQ, mantida por Scot Wingo. |
| [ 33.2 ] Como eu exibo um texto na barra de status usando MFC? |
| Use a seguinte codificação: |
CString s = "Text"; CStatusBar* p = (CStatusBar*)AfxGetApp()->m_pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR); p->SetPaneText(1, s);
| Isso funciona com MFC v.1.00. É de se esperar que funcione também com as versões posteriores. |
| [ 33.3 ] Como eu posso descompilar um executável de volta ao código fonte C++? |
| Você está brincando, não está? Aqui estão umas poucas das muitas razões pelas quais isso não é nem remotamente factível:
Mas a grande questão não é como descompilar o código de outros, mas porque você quer fazer isso? Se você está tentando engenharia reversa sobre o código de outros, é uma vergonha; procure um trabalho honesto. Se você está tentando recuperar um código fonte perdido, a melhor sugestão que tenho é fazer backups mais seguros da próxima vêz. |
| [ 33.4 ] Onde eu posso conseguir informações sobre compiladores C++ {Borland, IBM, Microsoft, Semantic, Sun, etc}? |
Em ordem alfabética pelo nome do vendedor:
Qualquer sugestão para acréscimos a essa lista deve ser enviada para cline@parashift.com ou arnaut@vicosa.com.br |
| [ 33.5 ] Como os compiladores usam over-allocation para lembrar o número de elementos em uma matriz alocada dinamicamente? |
| Recorde-se de que quando você delete[] uma
matriz, o sistema de execução sabe, como que por mágica,
quantos destrutores executar. Essa FAQ descreve uma técnica usada por alguns
compiladores C++ para conseguir isso. Uma outra ténica comum é usar uma matriz
associativa. Se o compilador usa a técnica over-allocation, o código para p = new Fred[n] se parecerá com o exemplo dado a seguir. Note que WORDSIZE é uma constante imaginária, dependente da máquina, que contém o valor de sizeof(size_t), possivelmente arredondado para o alinhamento correto. Em algumas máquinas essa constante tem um valor 4 ou 8. Esse não é um identificador real do C++ que será definido para o seu compilador. |
// Original code: Fred* p = new Fred[n];
char* tmp = (char*) operator new[] (WORDSIZE + n * sizeof(Fred));
Fred* p = (Fred*) (tmp + WORDSIZE);
*(size_t*)tmp = n;
size_t i;
try {
for (i = 0; i < n; ++i)
new(p + i) Fred(); // Placement new
} catch (...) {
while (i-- != 0)
(p + i)->~Fred(); // Explicit call to the destructor
operator delete[] ((char*)p - WORDSIZE);
throw;
}
| O comando delete[] p torna-se então em: |
// Original code: delete[] p; size_t n = * (size_t*) ((char*)p - WORDSIZE); while (n-- != 0) (p + n)->~Fred(); operator delete[] ((char*)p - WORDSIZE);
| Note que o endereço passado para operator delete[] não é o mesmo que p. Comparada à técnica matriz associativa, esta técnica é mais veloz, porém mais sensível ao problema de programadores escreverem delete p ao invés de delete[] p. Por exemplo, se você cometer um erro de programação, escrevendo delete p onde você deveria escrever delete[] p, o endereço passado para o operator delete(void*) não será o endereço de qualquer localização válida da memória de alocação dinâmica. Isso provavelmente vai corromper os controles de memória. Bang. Você está morto. |
| [ 33.6 ] Como os compiladores usam matriz associativa para lembrar o número de elementos em uma matriz alocada dinamicamente? |
| Recorde-se de que quando você delete[] uma
matriz, o sistema de execução sabe, como que por mágica,
quantos destrutores executar. Essa FAQ descreve uma técnica usada por alguns
compiladores C++ para conseguir isso. Uma outra ténica comum é over-allocate. Se o compilador usa a técnica matriz associativa, o código para p = new Fred[n] como exemplo seguinte, onde arrayLengthAssociation é o nome imaginário de uma matriz associativa global, oculta, que mapeia de void* a size_t: |
// Original code: Fred* p = new Fred[n];
Fred* p = (Fred*) operator new[] (n * sizeof(Fred));
size_t i;
try {
for (i = 0; i < n; ++i)
new(p + i) Fred(); // Placement new
} catch (...) {
while (i-- != 0)
(p + i)->~Fred(); // Explicit call to the destructor
operator delete[] (p);
throw;
}
arrayLengthAssociation.insert(p, n);
| O comando delete[] p torna-se então em: |
// Original code: delete[] p; size_t n = arrayLengthAssociation.lookup(p); while (n-- != 0) (p + n)->~Fred(); operator delete[] (p);
| Cfront usa essa técnica,
utilizando uma árvore AVL para implementar a matriz associativa. Comparada coma técnica over-allocation, a técnica matriz associativa é mais lenta, porém menos sensível ao problema de programadores escreverem delete p ao invés de delete[] p. Por exemplo, se você cometer um erro de programação escrevendo delete p, onde você deveria escrever delete[] p, apenas o primeiro Fred na matriz será destruído, mas a memória de alocação dinâmica vai sobreviver, a menos que você tenha substituído o operator delete[] por algo que simplesmente não invoca operator delete[], ou a menos que sejam necessários destrutores para outros objetos Fred. |
| [ 33.7 ] Se name mangling fosse padronizado, eu poderia ligar códigos compilados com diferentes compiladores de diferentes fornecedores? |
| Resposta curta: provavelmente não. Em outras palavras: algumas pessoas gostariam de ver padrões para name mangling incorporados à proposta de padronização C++ ANSI, numa tentativa de evitar ter que comprar diferentes versões de bibliotecas de classes para diferentes compiladores. Contudo, a diferença de name mangling é uma das menores diferenças entre as implementações de compiladores, mesmo quando para a mesma plataforma. Aqui está uma lista parcial das outras diferenças:
|
| [ 33.8 ] O compilador GNU C++ (g++) produz executáveis muito grandes para códigos fonte minúsculos. Porque? |
| ligb++ (a biblioteca usada pelo g++) provavelmente foi
compilada com opção de debug
information (-g). Em algumas máquinas, a
simples recompilação de libg++ sem opção de debug pode economizar muito espaço em
disco (aproximadamente 1MB); o lado negativo: você não terá como seguir a trilha das
chamadas libg++. Meramente strip-ping o executável não tem um efeito tão grande quanto uma
recompilação sem a opção -g seguida por
strip-ping o resultante a.out's. Use size a.out para verificar o quanto são realmente grandes o programa e os segmentos de dados, ao invés de ls -s a.out que inclui também a tabela de símbolos. |
| [ 33.9 ] A gramática yacc é compatível com C++? |
| Consta que a gramática yacc é bastante próxima do
C++. Até onde estou informado, ela não foi atualizada com os padrões C++, Por exemplo,
a gramática não trata templates, tratamento de exceções, nem identificação de tipos
em tempo de execução, e desvia-se do restante da linguagem em alguns casos mais sutis. A gramática yacc está disponível em http://srawgw.sra.co.jp/.a/pub/cmd/c++grammar2.0.tar.gz |
| [ 33.10 ] O que é C++ 1.2? 2.0? 2.1? 3.0? |
| Não propriamente versões da linguagem, ao
contrário, são versões de cfront, que foi o primeiro
tradutor para C++ implementado pela AT&T. Tornou-se aceito, de um modo genérico, usar
os números de versões do cfront com se fossem
identificadores de versões da própria linguagem. Em termos muito gerais, os principais recursos dessas versões são:
|
|
| | Home | Bookmarks | Universidades | Para Saber mais | Universidades | WEB Directory | Mapa do site | | |