Problemas con la implementación de Timsort de Swenson al ordenar estructuras

Encontré la implementación C de Swenson de Timsort: https://github.com/swenson/sort mencionado en una de las preguntas anteriores de SO.

Encontré dos problemas:

1) Para usarlo, necesito definir la macro SORT_CMP adecuada para el tipo que quiero ordenar. Mi tipo se define como (un poco simplificado aquí):

typedef struct{
    int a;
    int b;
} MyType

Trato de definir:

#define SORT_TYPE MyType
#define SORT_CMP(x,y) (x.a - y.a)

pero sigo recibiendo un error: "solicitud de miembro 'a' en algo que no es una estructura o unión" Pensé que tal vez x e y serían punteros pero:

#define SORT_CMP(x,y) (x->a - y->a)

tampoco funciona ¿Podrías ayudarme con eso? Soy novato en C y probablemente me falta algo básico.

2) ¿Hay alguna forma de compilar ese código en Visual Studio? Utiliza cosas del estándar C más nuevo (como declaraciones en el medio del bloque) y cl.exe no lo acepta. Lo compilé usando GCC (mingw) pero mingw es un 20 % más lento para el resto de mi código que VC (con el indicador O2 u O3 frente a lc.exe con /Ox), por lo que podría obtener cualquier ganancia al usar Timsort en lugar de stdlib qsort no compensará eso. Lo mismo ocurre con el compilador Pelles. La mayoría de mis datos tienen muchas secuencias parcialmente ordenadas y la ordenación toma alrededor del 50% del tiempo de ejecución, por lo que siento que hay ganancias aquí, suponiendo que lo haga funcionar en VC.

preguntado el 12 de junio de 12 a las 18:06

Publique un ejemplo pequeño y completo de un programa que use para tratar de ordenar una matriz simple de MyType registros y eso muestra el problema. -

El problema era que no compilaba nada; La respuesta aceptada lo resolvió. -

1 Respuestas

Puede intentar agregar paréntesis alrededor de los parámetros de las macros de la siguiente manera:

#define SORT_CMP(x,y) ((x).a - (y).a)

Lo más probable es que la macro se use con un puntero desreferenciado a una variable SORT_TYPE:

SORT_TYPE * pMyTypeVar1, pMyTypeVar2;
...
SORT_CMP(*pMyTypeVar, *pMyTypeVar2);

Si luego faltan esos paréntesis alrededor de los parámetros de la macro, el preprocesador produce algo como esto:

(*pMyTypeVar1.a - *pMyTypeVar2.a)

Y como el operador punto se une más fuerte que el operador estrella, el compilador intenta encontrar el miembro a para los punteros pMyTypeVar1 y pMyTypeVar2 que no funcionará.

El uso de paréntesis como se propone conduciría a:

((*pMyTypeVar1).a - (*pMyTypeVar2).a)

De esta manera, el compilador primero elimina las referencias pMyTypeVar1 y pMyTypeVar2 y finalmente es capaz de encontrar miembro a.

Respondido el 12 de junio de 12 a las 19:06

Gracias por esta explicación :) - Piotr Lopusiewicz

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.