¿Por qué los comentarios anidados están prohibidos en C++, Java a pesar del hecho de que los comentarios anidados son útiles, limpios y elegantes y se pueden usar para comentar declaraciones que tienen comentarios?¿Por qué están prohibidos los comentarios anidados?
Respuesta
C y C++ lo hacen para facilitar el análisis. De esta forma, cuando tocan un comentario de inicio de/*, el analizador puede escanear trivialmente hasta el final. De lo contrario, tendría que configurar y mantener una pila, y luego informar los errores si los tokens de comentarios no coinciden.
En cuanto a por qué lo hace Java, la respuesta es simple: la sintaxis de Java fue diseñada para emular C y C++, para engañar a las personas haciéndolas creer que era igual de rápido (al principio, Java fue puramente interpretado) necesario para obtener tracción). Si se permitieran los comentarios anidados, podrían tropezar a algunos programadores de C, ¡y se escribirían muchas publicaciones de blog enojadas!
¿Por qué necesitarías una pila para manejar los comentarios anidados? Simplemente mantenga un contador, incrementándolo cada vez que encuentre un '/ *' y disminuyéndolo cada vez que encuentre un '* /'. Cuando el contador es mayor que cero, arrojas los caracteres que encuentres (mientras sigues haciendo un seguimiento de '/ *' y '* /'); cuando el contador es cero, lee los tokens normalmente y se los entrega al analizador sintáctico; si el contador se vuelve negativo, informa una discrepancia entre los delimitadores de comentarios. Lo hace durante el análisis léxico, por lo que el analizador ni siquiera ve los comentarios. –
Conformidad/compatibilidad con C.
¿Acaso C no utilizó originalmente el símbolo // de comentario? Además, ¿por qué Java debería ajustarse al estándar C? – tloach
@tloach: '//' no existe en C antes de C99. – kennytm
C originalmente solo se usaba/* * /, y Java se diseñó intencionalmente después de C (y C++) para que sea más familiar para los programadores existentes. Conform es probablemente una palabra demasiado fuerte aquí, pero no estoy seguro de qué sería mejor. – ergosys
Al menos para C++ que es sólo parcialmente cierto, no hay problema:
/*
//
//
*/
Sin embargo, si usted ya tiene un * Comentarios/en una sección que desee comente que podría hacerlo rodeándolo con un #if 0
que creo que muchos compiladores optimizan. Como en:
#if 0
/*
*/
#endif
TODOS los compiladores optimizan eso, de la misma manera que "optimizan" múltiples veces, incluso cuando se usan protectores de encabezado, ya que es parte del paso de preproceso. –
Los compiladores no verán este bloque, el * preprocesador * lo habrá eliminado antes de que un compilador ponga sus ojos en el código :). – Pieter
@wowus: Sí, tienes razón, por supuesto. Estaba pensando en 'if (0)', que creo que depende del compilador. –
Es diferente para cada idioma (-familia) pero en general no están 'prohibidos', simplemente no son compatibles. Respaldarlos es una opción de diseño.
Una de las razones para la elección (para idiomas más antiguos) puede haber sido la facilidad de análisis.
Nota: Recuerdo un compilador de C++ en el que era una opción dejarlos anidar. Fue marcado como 'no estándar'.
Consideremos el siguiente ejemplo:
/* This is a comment /* Nested Comments */ are not allowed. */
Cualquier cosa que se encuentra entre /*
y */
se trata como un comentario. En el ejemplo anterior desde This
hasta Comments
, todo se trata como comentarios, incluido /*
. Por lo tanto, are not allowed. */
no se encuentra en el comentario. Esto es un error de sentencia C incorrecto.
Mientras que considere este ejemplo:
// This is an /* valid */ comment
Lo que se encuentra en la línea después de //
se trata como comentario. Dado que /* valid */
se encuentra en la misma línea después de //
, se trata como parte del comentario.
En los idiomas que permiten comentarios de longitud arbitraria, es muy común que los programadores comenten accidentalmente o, en algunos casos raros, "vuelvan a descomentar" en más o menos código de lo deseado. En muchos casos, tales errores darán lugar a errores de compilación, pero en otros casos pueden dar como resultado un código que simplemente se rompe. Con los editores modernos de resaltado de sintaxis, una regla que cada /*
incrementaría un contador de comentarios anidados y cada */
que lo disminuiría podría no causar demasiados problemas, pero sin resaltar la sintaxis, incluso tratando de descubrir qué código se comenta y qué código no fue No podría ser un gran dolor de cabeza.
Si se diseñó un lenguaje desde cero, un buen enfoque podría ser especificar marcas de inicio de comentario y fin de comentario que incluyan una cadena opcional, y hacer que el lenguaje exija un requisito de que la cadena en un La marca de fin de comentario debe coincidir con la cadena en su correspondiente marca de inicio de comentario. Suponiendo que la sintaxis era <|String|
y |String|>
, un compilador podría aceptar <|1| <|2| |2|> |1|>
, pero rechazar <|1| <|2| |1|> |2|>
. Incluso si se favorece el uso de las directivas #if
en lugar de comentarios, la capacidad de adjuntar marcadores para garantizar que cada directiva final se vincule con la directiva de inicio prevista sería útil.
El problema es que no se puede simplemente "omitir" bloques. los bloques tienen un número desconocido de bloques dentro de ellos, por lo que para saber cuándo se completa ese bloque, no puedes usar un lenguaje común, debes usar una pila y caminar por cada bloque hasta que la pila esté vacía, en ese punto usted sabe que el bloqueo está hecho.
La razón por la que no puede omitir bloques es que la expresión regular del bloque solo puede hacer coincidir el/* con "el primero */ve luego" o "el último */ve luego" o "enésimo */ve después".
Si vamos con el primer "* /" señal que vemos, podemos tener un código como
/*
/*
*/
the compiler matched /* with */ and this line and the next one will confuse it.
*/
Si vamos con el último "* /" señal que vemos, tenemos código en el compilador omitirá las cosas entre el primer comentario en el archivo y el último comentario del final del archivo. En este caso, el siguiente código se analizaría como una cadena vacía.
/*
/* hello, world! */
*/
int main(int argc, char ** argv) {
return 0;
}
/* end of file */
No podemos ir con la tercera opción de omisión de n bloques interiores sin obligar a todos los comentarios de tener el número exacto de la profundidad, de lo contrario no encontrará el comentario interior y confundirse.
En realidad, hay una cuarta opción que establece explícitamente que un comentario puede ser un comentario único, un comentario de 2 ámbitos, un comentario de 3 ámbitos, etc .; Pero hacer esto es feo, y cada nivel de profundidad requiere una expresión significativamente más larga, y este enfoque limita los comentarios a una profundidad específica que puede adaptarse a algunas personas y no a otras: ¿Qué pasaría si comenta un código que ha sido comentado? ¿3 veces?
La solución general se puede implementar con un pre-preprocesador tales como:
<?php
function stripComments($code) {
$stack = array();
$codeOut = '';
$stringStream = fopen('php://memory', 'r+');
fwrite($stringStream, $code);
rewind($stringStream);
while (!feof($stringStream)) {
$ch = fgetc($stringStream);
$nextChar = fgetc($stringStream);
if ($nextChar === false) {
break;
}
if ($ch == '/' && $nextChar == '*') {
array_push($stack, '/*');
} else if ($ch == '*' && $nextChar == '/') {
if (count($stack) > 0) {
array_pop($stack);
} else {
die('cannot pop from empty stack');
}
} else {
if (count($stack) == 0) {
$codeOut .= $ch;
fseek($stringStream, -1, SEEK_CUR);
}
}
$prevChar = $ch;
}
return $codeOut;
};
?>
que es un poco más complicado que lo que C utiliza actualmente:
function stripComments($code) {
return preg_replace('/\/\*[^\*\/]*\*\//', '', $code);
}
Esto no toma en consideración /**/
bloques dentro de comillas, se requiere una pila un poco más complicada que puede distinguir entre el alcance "/ *" y el "\" ".
El beneficio de tener comentarios dentro de los comentarios es que puedes comentar los bloques que contienen comentarios sin eliminar los comentarios manualmente, lo que es particularmente frustrante para los bloques que tienen comentarios en cada línea.
Sumario: Se puede hacer, pero la mayoría de los idiomas no desean tratar los comentarios como si fueran sus propios ámbitos, ya que requiere más esfuerzo analizarlos.
- 1. ¿Qué son los "patrones n + k" y por qué están prohibidos en Haskell 2010?
- 2. Comentarios anidados en C++
- 3. Comentarios anidados en XML?
- 4. ¿Cómo implementar un sistema de comentarios anidados?
- 5. ¿Por qué Scala no infiere completamente los parámetros de tipo cuando los parámetros de tipo están anidados?
- 6. ¿Por qué no se pueden inferir los tipos genéricos anidados?
- 7. content_tags anidados escape html interno ... ¿por qué?
- 8. ¿Por qué/**/comentarios funcionan en hojas de estilo pero // los comentarios no?
- 9. ¿Por qué los parámetros de `atan2`" están hacia atrás "?
- 10. ¿Por qué los bmps están almacenados al revés?
- 11. Por qué los emuladores de Android están numerados como 5554
- 12. ¿Por qué los OODBMS no están tan extendidos como RDBMS?
- 13. ¿Por qué los nombres de dominio están al revés?
- 14. Memcache + PHP - ¿Por qué los datos no están expirando?
- 15. ¿Por qué los inicializadores designados no están implementados en g ++
- 16. ¿Por qué los tipos de datos algebraicos Haskell "están cerrados"?
- 17. ¿Por qué los métodos de la clase Math están estáticos?
- 18. Los datos de JSON están entre corchetes ¿Por qué?
- 19. ¿Por qué los elementos de Stellar.js no se están moviendo?
- 20. ¿Qué caracteres NO están permitidos en los nombres de campo MongoDB?
- 21. ¿Se supone que los comentarios Pascal anidan?
- 22. Comentarios anidados/enhebrados/enhebrados estilo Reddit para Rails?
- 23. ¿Por qué los métodos de String.prototype están disponibles para los literales de cadena?
- 24. Aprobar automáticamente todos los comentarios en el complemento de comentarios
- 25. ¿Por qué mis pruebas funcionales están fallando?
- 26. ¿Por qué están relacionados SDL y OpenGL?
- 27. ¿Qué aplicación web recomendaría para los comentarios de los usuarios?
- 28. ¿Comentarios HTML dentro de los comentarios?
- 29. Django: quiero ordenar los comentarios por fecha y hora
- 30. ¿Por qué UIFont y CGFont/CTFont están separados por completo?
"fact"? De Verdad? –