Todos os idiomas podem ter erros semânticos e lógicos?


7

Eu tenho lido sobre PHP e muitos autores mencionam erros semânticos e lógicos separadamente. Como exemplo de erro semântico, eles fornecem uma função chamada com número incorreto de parâmetros: isso não será capturado pelo analisador, mas gerará um erro quando executado.

No entanto, em linguagens como C ++, isso será detectado pelo compilador. Eu diria que é um erro de sintaxe então. Qual é a diferença então entre um erro semântico e um lógico?

Por exemplo, em Como pensar como um cientista da computação , o autor usa "erro lógico" e "erro semântico" de forma intercambiável. Por outro lado, no Visual Basic .NET. Primer Plus , "erro lógico" é separado de "erro semântico".



Conheço as defesas, o problema é que ele não se aplica a todas as linguagens de programação da mesma maneira, conforme mencionado nas respostas. Não perguntei o que é erro semântico, sintático e lógico. Alguns autores consideram semântico um erro lógico, outros não.

11
Chamar uma função com argumentos errados não é um erro de sintaxe. É um erro de tipo e, portanto, semântico.

Algumas pessoas incluem semântica estática (nomes, tipos, ...) no termo "sintaxe", denotando efetivamente tudo o que pode ser (ou melhor, é) verificado pelo compilador como "sintaxe". "Semântica" é o que governa a execução do programa, por exemplo, despacho de método dinâmico. Não conheço uma definição formal de "erro lógico". Talvez você queira distinguir entre erro, falha e erro. Erros lógicos (pelo programador) causam falhas (no programa) que podem causar erros (em tempo de execução) que o compilador não pode excluir (por exemplo, NPE, div-por-zero, ...).
Raphael

Respostas:


7

Eu acho que provavelmente a explicação para alguns autores que usam "erro lógico" e "erro semântico" de forma intercambiável e para alguns autores que fazem uma distinção é simplesmente que eles não têm uma definição precisa universalmente aceita e, portanto, as pessoas estão usando a terminologia de maneira um pouco diferente. Eu não ficaria preso nisso.

Tanto a "lógica" quanto a "semântica" implicam algo a ver com o significado da programação; portanto, seria fácil considerá-las iguais.

Se eu fosse fazer uma distinção, uma útil que eu posso ver é que um erro lógico é quando o programa acaba significando algo diferente do que o programador pretendia, e um erro semântico é quando o programa acaba sem significar nada (consistente) em absoluto. Com essas definições, você pode considerar os erros lógicos como um superconjunto de erros semânticos ou que erros lógicos excluem erros que resultam na inconsistência do programa.

Por exemplo, o pseudo-código a seguir contém apenas um erro lógico:

x = read_number_from_user("x: ")
y = read_number_from_user("x: ")
print("The product of x and y is: ")
print(stringify(x + y))

O significado deste programa (tomado apenas como está e sem considerar a intenção do programador) é perfeitamente direto e consistente. Mas isso não significa o que o programador pretendia que isso significasse.

OTOH, o seguinte pseudo-código contém um erro semântico:

name = read_string_from_user("What is your name?")
print(name + 1)

Pelo menos, acontece se assumirmos que adicionar uma string e um número não significa nada. Em linguagens como PHP, isso significa alguma coisa, e isso não seria um erro semântico.

Seu exemplo de erro semântico no PHP como chamar uma função com um número incorreto de parâmetros é realmente interessante, porque é discutível se você deve chamar isso de erro semântico (com a definição que estou usando).

Funções são definidas dinamicamente em tempo de execução no PHP. Portanto, chamar uma função com um número incorreto de parâmetros pode ser considerado um erro lógico; talvez a instrução include incorreta tenha sido executada, fazendo com que uma função diferente com o mesmo nome seja incluída daquela para a qual a chamada deveria ir. Mesmo se não, chamar uma função com o número errado de argumentos significa alguma coisa ; significa procurar a função com esse nome e transmitir esses argumentos. É apenas operacionalmente em tempo de execução que o intérprete não consegue executar essas solicitações; da mesma x / ymaneira que significa alguma coisa, mas pode ser impossível realizar se yfor 0 no tempo de execução.

Por fim, como você classifica erros usando uma distinção como a que estou fazendo aqui entre erros lógicos e semânticos (mesmo que não seja exatamente o que estou cometendo) depende muito do idioma específico sobre o qual você está falando e como você atribuir significado aos programas no idioma . Os idiomas mais comumente usados não têm uma maneira padrão de atribuir significado a seus programas, o que significa que todos usam uma maneira ligeiramente diferente de fazê-lo (embora a interpretação de todos chegue a um acordo muito próximo de quase todos os efeitos operacionais ) e analise a "lógica" distinção "vs" semântica "de maneira diferente.

Outra maneira semelhante de ver isso seria dizer que os erros semânticos são o que faz com que a linguagem de programação rejeite o programa como inválido (além dos erros sintáticos, mais uma vez você pode chamar esses de subconjunto de erros semânticos, se quiser). Se a linguagem de programação aceita o programa, significa alguma coisa e, se falhar no tempo de execução, isso é resultado de um erro lógico. Isso praticamente atribui a implementação da linguagem de programação (intérprete, compilador + sistema de tempo de execução, qualquer que seja) como a definição do significado de programas.


3

É possível distinguir muitas categorias de erros em programas com base no ponto em que eles se manifestam. Algumas categorias não surgem em determinados contextos (dependendo da linguagem de programação, de como o programa é projetado, de como o programa é usado ...). A terminologia varia muito entre as comunidades. Vou mostrar uma tipologia das principais categorias; Tenha em mente que

  • existem fluxos de trabalho em que algumas dessas categorias não serão aplicadas;
  • existem fluxos de trabalho onde é conveniente fazer outras distinções;
  • erros semelhantes podem terminar em categorias diferentes, dependendo da linguagem de programação e das ferramentas usadas;
  • pessoas diferentes têm terminologias diferentes, os nomes que dou são plausíveis, mas de modo algum consensuais.

Você pode distinguir diferentes categorias de erros com base no ponto em que são notados.

  1. Erros de sintaxe
    O compilador ou intérprete informa que o que você escreveu nem faz sentido. Na maioria dos idiomas, esse é um erro fatal, que não permitirá que o programa comece a ser executado.
    Exemplo: um parêntese próximo ausente.

  2. Erros de tipo estático e outros erros do compilador
    O compilador ou intérprete informa que, embora entenda o que você solicitou, isso não faz sentido. A distinção entre erros de sintaxe e outros tipos de erros do compilador é uma questão de design interno do compilador ou, às vezes, do design da linguagem de programação.
    Exemplo: usando uma variável que não foi definida (isso geralmente é considerado um erro de sintaxe, mas nem sempre)

    Em linguagens de tipo estaticamente, o compilador rejeita programas que tentam alguns tipos de operações inválidas. Em linguagens de tipo dinâmico, esses erros são erros de tempo de execução, fatais ou não. Exemplo: tentando dividir um número inteiro por uma sequência.

  3. Erros de inicialização
    Essa é a primeira categoria de erros que é revelada à pessoa que executa o programa, e não à pessoa que o executa.
    O programa não inicia ou não alcança um estado em que realmente faz alguma coisa.
    Exemplo: tentando usar uma biblioteca externa que não está presente no sistema.
    Exemplo: qualquer erro de sintaxe ou de compilação em um idioma interpretado (onde o programador distribui o código fonte).

  4. Erros fatais de tempo de execução
    Em algum momento, o programa para de funcionar.
    Exemplo: violação de acesso à memória (tentando acessar a memória que não está alocada para o programa)
    Observe que programas suficientemente complexos podem tentar detectar praticamente qualquer erro, transformando-os em erros recuperáveis.

  5. Erros de tempo de execução inesperados, mas recuperáveis
    Alguns componentes do programa param de funcionar, mas o programa continua. Exemplo: falta de memória (se o programa foi projetado para lidar com isso normalmente)
    Exemplo: um processo em um aplicativo multiprocesso falha, mas os outros processos continuam em execução

  6. Erros esperados de tempo de execução
    Alguma condição de erro é esperada, mas foi programada para. Este é apenas um comportamento normal, reagindo a um evento externo que é de alguma forma "ruim", mas que pode acontecer. Quando você considera o programa como um todo, esses realmente não são erros.
    Exemplo: arquivo não encontrado
    Exemplo: desconexão da rede
    Exemplo: entrada de usuário inválida

  7. Erros de
    programação O programa está fazendo algo, mas não é o que deveria estar de acordo com sua especificação. Há uma diferença entre o que o programador pretendia fazer e o que o código-fonte realmente significa.
    Exemplo: um aplicativo Web deve permitir o upload de um arquivo, mas não funciona em nomes de arquivos que contenham espaços; o aplicativo rejeita o arquivo e continua trabalhando.
    Exemplo: um programa projetado para multiplicar algum número retorna um resultado, mas a operação matemática não é realizada corretamente.

  8. Erros de especificação
    O programa está fazendo algo e está em conformidade com sua especificação ou documentação. No entanto, após reflexão, o comportamento do programa nessa situação não é bom. (“Não é bom”, é claro, é um julgamento subjetivo.)
    Exemplo: o componente 1 espera uma lista delimitada por espaço de nomes de arquivos. O componente 2 envia um único nome de arquivo que contém espaços. Os dois componentes não foram cuidadosamente projetados para trabalhar juntos.
    Exemplo: um programa para prever o clima anuncia a chuva que não chega, porque a modelagem do mundo físico não foi boa o suficiente.

É bastante típico considerar 2–4 como erros semânticos e 7–8 como erros lógicos. (No entanto, observe novamente que a terminologia pode variar.) Erros de tempo de execução recuperáveis ​​não são erros do programa como um todo, mas podem ser vistos como erros de tempo de execução de alguma parte dele.

Existe uma terminologia diferente que considera que

  • erros semânticos são o que um compilador com um sistema de tipo estático normalmente capturaria ou o que faria com que um sistema de tempo de execução "protetor" abortasse um programa com uma exceção que não se deva a um evento externo (por exemplo, método não encontrado em vez de arquivo não encontrado);
  • erros de lógica são o que não seriam detectados.

Essa pode ser uma distinção bastante precisa quando você considera um idioma específico e um verificador de tipo específico. No entanto, quando as pessoas usam esses termos, geralmente têm uma ideia muito imprecisa sobre o que seria esse compilador hipotético. Por exemplo, se você estiver programando em Java, transmitir o número errado de argumentos é capturado pelo compilador. Se você está programando em PHP, é capturado pelo sistema de tempo de execução. Se você estiver programando em Perl, é provável que não seja capturado (na ausência de qualquer declaração de argumento, argumentos extras são ignorados e argumentos ausentes produzem um valor padrão).

Ou, para dar outro exemplo: suponha que você tenha uma matriz de 10 elementos e tente acessar a 11ª. Em alguns idiomas, como C, isso faz com que o programa acesse uma zona de memória não relacionada, levando a um comportamento imprevisível. Em outros idiomas, isso faz com que uma exceção seja lançada; dependendo se o programador esperava isso, isso pode ser um erro semântico (o programador esperava que o índice estivesse fora dos limites, mas não verificou essa situação), um erro lógico (o programador pensou erroneamente que o índice sempre seria válido ) ou nenhum erro (o programador contou com a exceção para testar se o índice da matriz estava dentro dos limites da matriz).

A moral da história é que essas classificações são altamente variáveis. Não dê muita importância a quais erros são colocados em quais categorias por quais autores. O importante é entender a relação entre o que você escreve e o que o programa deve fazer. Como programador, seu trabalho é trazer uma enorme lacuna entre o que escrevo e o que quero dizer . Se algo cair na brecha, não se prenda a colocar uma etiqueta; concentre-se em entender o que está errado e como corrigi-lo.


"o que você escreveu nem faz sentido" vs "que não faz sentido" não é uma distinção muito clara. Eu acho que seria útil dizer "falha na análise do CFG -> erro de sintaxe. Rest (no compilador) -> semântica estática". Além disso, acho que a resposta se beneficiaria da distinção entre erro, falha e erro (como eu os expliquei / defini no meu comentário sobre a questão).
Raphael

A distinção de tipos de erro pode ser útil para escolher uma linguagem de programação para um determinado projeto. Em alguns ambientes (sistemas criticial de segurança, por exemplo) que você quer tantos erros quanto possível capturados pelo compilador, para provably excluir tantos erros quanto possível. Para esse fim, existem até compiladores que entendem e verificam especificações formais (simples) (que captariam "erros lógicos").
Raphael

1

Basicamente, você deve examinar primeiro os idiomas.

PHP é uma linguagem de intérprete, o que significa que os scripts são compilados e executados toda vez no tempo de execução. C ++ é uma linguagem de compilador, o que significa que os scripts são compilados com um compilador uma vez no tempo de construção e podem ser executados.

portanto, os dois compiladores reconhecem o erro semântico do seu exemplo, mas o compilador php faz isso em tempo de execução e o compilador c ++ em tempo de compilação.

Uma boa explicação para sua pergunta pode ser encontrada na Wikipedia e aqui (diferença entre semântica e sintaxe)


Isso está errado. Normalmente, o PHP também é compilado e, com um cache de opcode, sua fase de compilação é separada da fase de execução. A verdadeira razão para a diferença é que o C ++ usa digitação e verificação de tipo muito mais fortes que o PHP. É claro que digitação forte e compilação separada geralmente andam juntas, mas, estritamente falando, elas não precisam.
Reinierpost

0

Meu palpite:

  • Um erro semântico (al) é um erro de programação que produz código sintaticamente válido, mas que não pode fazer o que seu programador pretendia, não importando qual fosse a intenção. O código está definitivamente errado e pode ser sinalizado como tal por ferramentas de software - embora as ferramentas de software não possam sinalizar todos esses erros (pelo Teorema de Rice).
  • Um erro lógico (al) é um erro de programação que produz código sintaticamente válido, mas não faz o que seu programador pretendia, embora possa estar correto se o programador tiver uma intenção diferente. O código está errado apenas devido às intenções do programador; ferramentas de software não podem sinalizar o código como errado, o melhor que podem fazer é sugerir a possibilidade desse erro.

0

Um programa é um texto destinado a expressar a computação de um resultado que responde a uma pergunta sobre os dados. Por exemplo, um programa de classificação pega uma lista de valores (os dados) e deve calcular um resultado que é outra lista dos mesmos valores, mas classificados de acordo com alguma função de comparação.

Este texto deve ser expresso formalmente em algum tipo de linguagem que é (ou deveria ser) definida com precisão, tanto em relação ao que constitui um texto legítimo de programa quanto em como algum significado computacional pode ser associado a esse texto. Essa definição precisa é geralmente abstrata (possivelmente matemática) e pode ignorar alguns problemas concretos, como limitações do computador.

Mas então, a linguagem é implementada para que os programas possam ser executados. Existem várias maneiras de executar essa implementação, usando um intérprete do texto original do programa ou compilando para algum código intermediário (código de bytes, por exemplo), e possivelmente interpretando esse código intemediato ou compilando-o ainda mais no código da máquina. E pode haver outras variações. E, é claro, existem muitas maneiras de escrever um compilador ou um intérprete e muitas máquinas para executá-los.

Além disso, pode haver várias definições formais e várias implementações, esperançosamente consistentes.

Os erros podem ser classificados em relação à estrutura de uma ou de uma definição formal ou de uma implementação. No entanto, você pode ter situações estranhas em que os erros são classificados de acordo com uma implementação de referência antiga que não é mais a que está sendo usada.

Isso significa essencialmente que a classificação dos erros não é realmente um tópico muito estável . Além disso, algumas linguagens podem distinguir vários níveis de erros, dependendo se algo está definitivamente errado (o programa nem será executado) ou se você está fazendo algo não recomendado, mas isso ainda produzirá algum cálculo, que pode fazer sentido. Isso até se reflete em recursos de linguagens de programação, como exceções, que podem ou não ser recuperadas.

Distinções padrão são:

Erros de sintaxe : o texto fornecido não está em conformidade com a estrutura de um texto de programa, independentemente do que ele deva significar. Isso pode se referir apenas a uma sintaxe formal de linguagem, geralmente sem contexto. Às vezes, pode ir além e incluir a verificação de alguns recursos básicos, como declarações de variáveis ​​(se houver) ou consistência de tipo, embora esses também possam ser considerados como erros semânticos.

Erros semânticos ou lógicos : são erros que podem ser detectados ao executar o programa, devido ao fato de o programa executar um cálculo que não faz sentido semântico, como dividir por zero ou indexar uma matriz fora do intervalo. limites. Chamar uma função com o número errado de argumentos ou com argumentos do tipo errado também pode ser considerado um erro semântico. Em alguns idiomas, os erros podem realmente ser definidos pelo usuário por meio de exceções, quando correspondem a alguma semântica de nível superior definida pelo usuário para parte de seu programa (embora haja outros usos de exceções). Alguns desses erros também são chamados de erros em tempo de execução, pois são detectados em tempo de execução, mas não devem ser confundidos com erros de limitação de hardware.

Erros de limitação de hardware : são erros devido ao fato de a implementação estar em uma máquina real que possui limitações. Por exemplo, pode ser um número inteiro grande demais para caber em uma palavra de memória ou falta de memória suficiente para criar uma estrutura de dados. Eles também geralmente são detectados em tempo de execução.

Em relação aos erros semânticos e erros de limitação de hardware, às vezes é possível detectá-los antes de executar o programa, com o que é chamado de análise semântica estática. Esse é geralmente o caso de declarações ou variáveis ​​não inicializadas, erros de tipo ou divisão por zero e alguma verificação vinculada à matriz, mas isso pode ir muito além. A análise semântica estática também é importante nos compiladores para muitas técnicas de otimização. Geralmente, existe uma separação entre semântica estática e dinâmica. A melhor definição que posso imaginar é que a semântica estática diz respeito a propriedades que são decidíveis em tempo de compilação, sem os dados reais. Portanto, a divisão por zero não faria parte da semântica estática em geral. Isso significa que alguns erros semânticos dinâmicos ainda podem ser detectados às vezes em tempo de compilação. O mesmo vale para erros de limitação de hardware.

Porém, todo designer ou implementador de linguagem tem o direito de classificar os erros como deseja , a menos que esteja vinculado a um contrato ou licença. Esse pode ser o caso do seu exemplo PHP. E qualquer um pode também fazer uma distinção entre erros semânticos e lógicos, embora eu não saiba como definir uma diferença, a menos que seja informado em detalhes sobre esses erros. Um poderia ser usado para indicar erro de intenção (erro lógico) e não seria detectável pelo sistema.

Observe que pode haver outros tipos de erro em um programa , que geralmente não serão detectados pelo sistema. Isso inclui, em particular, inconsistências do programa com sua especificação (ou o que chamei de erro de intenção: o usuário não está fazendo o que ele quis fazer), ou possivelmente erros na própria especificação. Também pode haver erros devido a limitações de hardware, como erros de arredondamento ao trabalhar com números reais.


-2

De acordo com as notas do meu curso de computação superior, erros semânticos e erros lógicos são apenas nomes diferentes para a mesma coisa.


11
Erros semânticos são diferentes dos erros lógicos.
Juho

11
Infelizmente, isso não é útil. Você está discordando das outras respostas, mas a única explicação que você oferece é um apelo à autoridade ("Meu professor diz isso!").
precisa saber é o seguinte
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.