2009-05-28 13 views
1

J'ai un programme C++ natif qui utilise des "files d'attente d'événements" pour exécuter des fonctions sur différents threads. J'attribue une classe "event" sur le tas, et la place sur l'une des files d'attente de mes threads pour l'exécution.Comment utiliser le préprocesseur pour calculer et stocker des hachages lors de la compilation?

Tout fonctionne très bien, mais il est très difficile de retracer l'origine de ces "événements". Je voudrais que chaque "événement" stocke quelques informations concernant d'où il vient. En ce moment j'utilise _ReturnAddress() intrinsèque pour cela, mais je voudrais aussi avoir la chaîne de nom de fichier et le numéro de ligne. Je suis d'accord avec l'utilisation de macros pour planifier mes "événements".

Bien sûr, je ne veux pas payer le prix pour avoir ces chaînes.

Y at-il un moyen d'avoir le préprocesseur construire et vider pour classer une carte de "id" => "fichier, ligne", où le "id" serait un nombre unique incrémenté chaque fois que ma macro est élargie ? Je pourrais stocker cet identifiant comme mon origine.

Ou peut-être de calculer un hachage très court du nom de fichier afin que je puisse l'utiliser lors de l'exécution?

Toutes les idées sont les bienvenues.

Répondre

4

Pour ID, vous pouvez utiliser __COUNTER__.

De http://msdn.microsoft.com/en-us/library/b0084kay(VS.80).aspx:

Développe à un nombre entier en commençant par 0 et incrémenter par 1 à chaque fois qu'il est utilisé dans un compiland.

__FILE__ et __LINE__ peuvent être utilisés pour suivre où l'événement a été alloué. Mais pourquoi voulez-vous retracer l'origine de ces événe- ments? Si c'est à des fins de débogage, vous pouvez envisager d'incorporer une trace de pile, collectée à l'aide de StackWalk64, dans votre classe en mode de débogage spécial - cela vous donnera beaucoup plus d'informations utiles que le lieu d'origine.

+0

Une idée intéressante. Je vais devoir regarder dans StackWalk64 un peu plus. La raison pour laquelle je veux l'origine est à des fins de traçage au cas où l'application se bloque. Il échoue presque toujours dans la boucle des messages, donc je n'ai aucune idée d'où vient le message. J'ai un peu de traçage pour les versions de débogage, mais j'aimerais aussi quelque chose pour la production. –

+0

Je regarderais certainement dans StackWalk64 alors.Vous pourriez rencontrer des problèmes si vous générez un très grand nombre d'événements sur une courte période (par exemple des dizaines de milliers de secondes ou plus), alors le coût de StackWalk peut être prohibitif pour être tout le temps. – Michael

3

Écrivez votre propre préprocesseur.

Ne doit pas être si difficile, analyse simplement le fichier .cpp et recherche une syntaxe que vous avez définie vous-même. Lorsque vous le trouvez, ajoutez le nom et la ligne du fichier (le préprocesseur devra compter le nombre de nouvelles lignes) dans un fichier journal. Il faudrait cependant développer votre propre macro en C++. Ecrivez tout dans un fichier temporaire, que vous transmettez ensuite au "vrai" compilateur.

À la votre!

1

Découvrez Boost.Preprocessor. C'est un ensemble de macros en-tête seulement pour faire des choses puissantes avec le préprocesseur C standard.

C'est assez compliqué (je ne prétends pas le comprendre) mais je pense qu'il peut faire ce que vous voulez. Docs here et here.