2012-03-09 8 views
5

Tengo un código de actuación CUDA sensible, lo que estoy usandoCómo obtener Emacs para manejar adecuadamente C preprocesador condicionales

#ifdef DEBUG_<NAME_OF_SECTION> 
    ... 
#else 
    ... 
#endif 

... condicionales para encapsular el código de depuración velocidad paralizando, que agarra información adicional de descanso la GPU.

Todo va bien en emacs (Centos 6.0) hasta el #else.

Este deindents (por 1 pestaña) del texto dentro de la cláusula else del preprocesador condicional y sigue deindent todo después.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Nota: ) replicación dentro del preprocesador condicional parece ser manejado adecuadamente por el modo C Pero la duplicación ); rompe las cosas, lo que le obliga a mover el ); fuera del condicional ... oh querido lo inconsistente. Mantendré abierta esta pregunta hasta que obtengamos el código elisp adecuado para solucionar esta incoherencia. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

NOTA en la respuesta actual:
Jens ha proporcionado información inexacta al afirmar que la sangría anidada ) dentro de condicionales es "imposible". No solo es posible, sino que el modo C de Emacs lo hace de forma activa. Tenga en cuenta la sangría adecuada del programa de ejemplo c al final de esta publicación de la pregunta como prueba de ello. Por lo tanto, sería lógico pensar que ); también es posible para sangrar, aunque se debe tener precaución por los motivos descritos por Jens.

De todos modos, quiero asegurarme de que las personas vean que la declaración es incorrecta, por lo que no creen que esta pregunta no sea contestable. Voy a eliminar este comentario y mi downvote en el poste de Jens cuando modifica sus afirmaciones inexactas para reflejar que es posible, se implementa en C-modo para el caso de ) esboza, pero no se recomienda.

Actualmente, estoy recurriendo al reescalado manual de las cosas una sola pestaña, pero está perdiendo mucho tiempo (el código es largo).

Alguna idea de lo que puedo añadir a mi archivo ~/.emacs para solucionar este problema ???

¡Gracias de antemano!

EDIT 1 Debo mencionar que la cláusula en la que parece asfixiarse es una función que se cierra, p.

 MyFunc<<<Blk,Thr>>>(Stuff1, 
    #ifdef DEBUG_FUNC1 
          Stuff2, 
          dev_Debug); 
    #else 
         Stuff2); //Deindents here. 
    #endif 
    //Everything here on out is deindented. 

Puede ser una falla específica sobre ese tipo de estructura de código ...

EDIT 2 Aquí hay una versión de C simplemente el código ... el código funciona como se esperaba, pero no el deindent en la última cláusula #else ...

#include <stdio.h> 

//#define DEBUG 

void printer 
(int A, 
#ifdef DEBUG 
int B, 
int C) 
#else 
int B) 
#endif 
{ 
#ifdef DEBUG 
    printf("A: %i, B: %i, C: %i\n", A, B, C); 
#else 
    printf("A: %i, B: %i\n", A, B); 
#endif 
} 

int main() 
{ 
    int A = -3; 
    int B = 1; 
    int C = 3; 
    printer(A, 
#ifdef DEBUG 
     B, 
     C); 
#else 
    B); 
#endif 
    return 0; 
} 

... eso es a lo largo de las líneas de lo que estoy haciendo.Sé que funciona sintácticamente en C (o al menos creo que ... da resultados correctos), sin embargo a emacs no le gusta esa cláusula #else dentro de la llamada de función ....

+0

Si cuenta el número de llaves de apertura y cierre ('{}') en el código entre '# ifdef' y' # else', ¿coinciden todas? –

+0

Ver el ejemplo ... no hay '{}' ... en la sección de preprocesador que se está ahogando. Parece que no me gusta usar el preprocesador más dentro de una llamada a función. Publique un ejemplo que no sea CUDA para que pueda mostrar lo que quiero decir ... –

+1

Considere poner más (por ejemplo, una definición duplicada si es necesario) en cada rama. Sospecho que se debe al ")" en la primera ruta. –

Respuesta

3

Creo que el problema es en la lógica de tu código. Lógicamente tiene diferentes parámetros en una lista de parámetros de función. El paréntesis de cierre no debe ser parte del condicional.

MyFunc<<<Blk,Thr>>>(
         Stuff1, 
#ifdef DEBUG_FUNC1 
         Stuff2, 
         dev_Debug 
#else 
         Stuff2 
#endif 
        ); 

O, alternativamente, usted debe tener dos versiones completas del prototipo que se elige en función de la macro de depuración. Todo lo demás no solo es difícil de analizar para emacs (o probablemente cualquier otro editor) sino también para el pobre humano que viene después de ti.

Lo que queremos no es posible ya que el nivel de sangría de un código podría depender de las macros:

#if A 
(
#endif 
something 
#if B 
) 
#endif 

donde A y B son los mismos para todas las compilaciones válidos. Emacs no puede saber sin asumir los valores de A y B, cómo sangrar.

+0

Mi código es sintácticamente correcto y compila ... puede ser de mala calidad, pero incluyo un casquillo ');' en cada arg-set de cierre. Sin convertir esto en un debate sobre estándares de codificación, ¿por qué no se puede manejarlo si es sintácticamente correcto? –

+0

Vea el ejemplo C simple anterior si no me cree que la sintaxis funciona. Ahora, su solución funciona, pero me gustaría tratar de obtener una respuesta sobre por qué emacs c handler carnicerías mi alternativa, pero una sintaxis válida y cómo prevenir eso ... hasta que obtengo esa respuesta, esta pregunta permanece abierta de principio, pero te estoy evaluando porque estoy usando tu solución como una alternativa. ;) –

+0

@Jason, porque elisp es lisp. Su analizador es profundamente dependiente de la exploración para el paréntesis de cierre (en un sentido amplio). C es diferente, analiza el código en fases y reemplaza sintácticamente (o elimina) partes del texto. De alguna manera, desea tener la identación del código para cualquier valor posible de las macros del preprocesador. Para un blob dado, no hay garantía de que la sangría calculada de esa manera sea siquiera algo único. –

Cuestiones relacionadas