Recherche…


Introduction

Le préprocesseur C est un analyseur / remplaçant de texte simple exécuté avant la compilation du code. Utilisé pour étendre et faciliter l'utilisation du langage C (et plus tard C ++), il peut être utilisé pour:

une. Y compris d'autres fichiers en utilisant #include

b. Définir une macro de remplacement de texte à l' aide de #define

c. Compilation conditionnelle utilisant #if #ifdef

ré. Logique spécifique à la plate-forme / au compilateur (en tant qu'extension de la compilation conditionnelle)

Remarques

Les instructions de préprocesseur sont exécutées avant que vos fichiers source ne soient remis au compilateur. Ils sont capables d'une logique conditionnelle de très bas niveau. Étant donné que les constructions de préprocesseur (par exemple, les macros de type objet) ne sont pas typées comme des fonctions normales (l'étape de prétraitement se produit avant la compilation), le compilateur ne peut pas appliquer les vérifications de type.

Inclure les gardes

Un fichier d'en-tête peut être inclus par d'autres fichiers d'en-tête. Un fichier source (unité de compilation) comprenant plusieurs en-têtes peut donc, indirectement, inclure plusieurs en-têtes plus d'une fois. Si un tel fichier d'en-tête contient plus d'une fois des définitions, le compilateur (après prétraitement) détecte une violation de la règle One Definition (par exemple, §3.2 du standard C ++ 2003) et émet un diagnostic et la compilation échoue.

L'inclusion multiple est empêchée en utilisant "include guards", qui sont parfois aussi appelés gardes d'en-tête ou macro-gardes. Celles-ci sont implémentées en utilisant les directives de préprocesseur #define , #ifndef , #endif .

par exemple

// Foo.h
#ifndef FOO_H_INCLUDED 
#define FOO_H_INCLUDED

class Foo    //  a class definition
{
};

#endif

Le principal avantage de l'utilisation des gardes inclus est qu'ils fonctionneront avec tous les compilateurs et préprocesseurs conformes aux normes.

Cependant, les gardes d'inclusion posent également des problèmes aux développeurs, car il est nécessaire de s'assurer que les macros sont uniques dans tous les en-têtes utilisés dans un projet. Plus précisément, si deux en-têtes (ou plus) utilisent FOO_H_INCLUDED comme garde d'inclusion, le premier de ces en-têtes inclus dans une unité de compilation empêchera effectivement l'inclusion des autres. Des défis particuliers sont présentés si un projet utilise un certain nombre de bibliothèques tierces avec des fichiers d'en-tête qui utilisent des gardes en commun.

Il est également nécessaire de s’assurer que les macros utilisées dans les protections d’inclusion n’entrent pas en conflit avec d’autres macros définies dans les fichiers d’en-tête.

La plupart des implémentations C ++ prennent également en charge la directive #pragma once qui garantit que le fichier n'est inclus qu'une seule fois dans une seule compilation. C'est une directive standard de facto , mais elle ne fait partie d'aucune norme ISO C ++. Par exemple:

// Foo.h
#pragma once

class Foo
{
};

Alors que #pragma once évite certains problèmes associés aux gardes d'inclusion, un #pragma - par définition dans les standards - est intrinsèquement un hook spécifique au compilateur, et sera ignoré par les compilateurs qui ne le supportent pas. Les projets qui utilisent #pragma once sont plus difficiles à porter sur des compilateurs qui ne le prennent pas en charge.

Un certain nombre de directives de codage et de normes d'assurance pour C ++ découragent spécifiquement toute utilisation du préprocesseur autre que les fichiers d'en-tête #include ou pour les placer dans les en-têtes.

Logique conditionnelle et gestion multi-plateforme

En bref, la logique de pré-traitement conditionnel consiste à rendre la logique de code disponible ou non disponible pour la compilation à l'aide de définitions de macro.

Trois cas d'utilisation importants sont:

  • différents profils d'application (par exemple, débogage, publication, test, optimisé) pouvant être candidats de la même application (par exemple, avec une journalisation supplémentaire).
  • compilations multi-plateformes - base de code unique, plusieurs plates-formes de compilation.
  • utiliser une base de code commune pour plusieurs versions d'application (par exemple, versions Basic, Premium et Pro d'un logiciel) - avec des fonctionnalités légèrement différentes.

Exemple a: Une approche multi-plateforme pour la suppression de fichiers (illustrative):

#ifdef _WIN32
#include <windows.h> // and other windows system files
#endif
#include <cstdio>

bool remove_file(const std::string &path) 
{
#ifdef _WIN32
  return DeleteFile(path.c_str());
#elif defined(_POSIX_VERSION) || defined(__unix__)
  return (0 == remove(path.c_str()));
#elif defined(__APPLE__)
  //TODO: check if NSAPI has a more specific function with permission dialog
  return (0 == remove(path.c_str()));
#else 
#error "This platform is not supported"
#endif
}

Des macros comme _WIN32 , __APPLE__ ou __unix__ sont normalement prédéfinies par les implémentations correspondantes.

Exemple b: Activation de la journalisation supplémentaire pour une génération de débogage:

void s_PrintAppStateOnUserPrompt()
{
    std::cout << "--------BEGIN-DUMP---------------\n"
              << AppState::Instance()->Settings().ToString() << "\n"
#if ( 1 == TESTING_MODE ) //privacy: we want user details only when testing
              << ListToString(AppState::UndoStack()->GetActionNames())
              << AppState::Instance()->CrntDocument().Name() 
              << AppState::Instance()->CrntDocument().SignatureSHA() << "\n"
#endif
              << "--------END-DUMP---------------\n"
}

Exemple c: Activer une fonctionnalité premium dans une version de produit distincte (remarque: ceci est illustratif. Il est souvent préférable d'autoriser le déverrouillage d'une fonctionnalité sans avoir à réinstaller une application)

void MainWindow::OnProcessButtonClick()
{
#ifndef _PREMIUM
    CreatePurchaseDialog("Buy App Premium", "This feature is available for our App Premium users. Click the Buy button to purchase the Premium version at our website");
    return;
#endif
    //...actual feature logic here
}

Quelques astuces communes:

Définition des symboles au moment de l'invocation:

Le préprocesseur peut être appelé avec des symboles prédéfinis (avec une initialisation facultative). Par exemple cette commande ( gcc -E exécute uniquement le préprocesseur)

gcc -E -DOPTIMISE_FOR_OS_X -DTESTING_MODE=1 Sample.cpp

traite Sample.cpp de la même manière que si #define OPTIMISE_FOR_OS_X et #define TESTING_MODE 1 étaient ajoutés au début de Sample.cpp.

S'assurer qu'une macro est définie:

Si une macro n'est pas définie et que sa valeur est comparée ou vérifiée, le préprocesseur assume presque toujours en silence la valeur 0 . Il y a plusieurs façons de travailler avec cela. Une approche consiste à supposer que les paramètres par défaut sont représentés par 0 et que toute modification (par exemple, le profil de génération de l'application) doit être explicitement effectuée (par exemple ENABLE_EXTRA_DEBUGGING = 0 par défaut, définissez -DENABLE_EXTRA_DEBUGGING = 1). Une autre approche consiste à rendre toutes les définitions et les valeurs par défaut explicites. Cela peut être réalisé en utilisant une combinaison de directives #ifndef et #error :

#ifndef (ENABLE_EXTRA_DEBUGGING)
// please include DefaultDefines.h if not already included.
#    error "ENABLE_EXTRA_DEBUGGING is not defined"
#else
#    if ( 1 == ENABLE_EXTRA_DEBUGGING )
  //code
#    endif
#endif

Macros

Les macros sont classées en deux groupes principaux: les macros de type objet et les macros de type fonction. Les macros sont traitées comme une substitution de jeton au début du processus de compilation. Cela signifie que des sections de code volumineuses (ou répétitives) peuvent être extraites dans une macro de préprocesseur.

// This is an object-like macro
#define    PI         3.14159265358979

// This is a function-like macro.
// Note that we can use previously defined macros
// in other macro definitions (object-like or function-like)
// But watch out, its quite useful if you know what you're doing, but the
// Compiler doesnt know which type to handle, so using inline functions instead
// is quite recommended (But e.g. for Minimum/Maximum functions it is quite useful)
#define    AREA(r)    (PI*(r)*(r))

// They can be used like this:
double pi_macro   = PI;
double area_macro = AREA(4.6);

La bibliothèque Qt utilise cette technique pour créer un système de méta-objets en demandant à l'utilisateur de déclarer la macro Q_OBJECT en tête de la classe définie par l'utilisateur qui étend QObject.

Les noms de macro sont généralement écrits en majuscules pour les différencier plus facilement du code normal. Ce n'est pas une exigence, mais est simplement considéré comme un bon style par de nombreux programmeurs.


Lorsqu'une macro de type objet est rencontrée, elle est développée sous la forme d'une simple opération de copier-coller, le nom de la macro étant remplacé par sa définition. Lorsqu'une macro de type fonction est rencontrée, son nom et ses paramètres sont développés.

double pi_squared = PI * PI;
// Compiler sees:
double pi_squared = 3.14159265358979 * 3.14159265358979;

double area = AREA(5);
// Compiler sees:
double area = (3.14159265358979*(5)*(5))

De ce fait, les paramètres de macro de type fonction sont souvent placés entre parenthèses, comme dans AREA() ci-dessus. Cela permet d'éviter tout bogue pouvant survenir lors de l'expansion d'une macro, en particulier les bogues causés par un paramètre de macro unique composé de plusieurs valeurs réelles.

#define BAD_AREA(r) PI * r * r

double bad_area = BAD_AREA(5 + 1.6);
// Compiler sees:
double bad_area = 3.14159265358979 * 5 + 1.6 * 5 + 1.6;

double good_area = AREA(5 + 1.6);
// Compiler sees:
double good_area = (3.14159265358979*(5 + 1.6)*(5 + 1.6));

Notez également qu'en raison de cette simple extension, les paramètres transmis aux macros doivent être pris en compte pour éviter les effets secondaires inattendus. Si le paramètre est modifié pendant l'évaluation, il sera modifié à chaque fois qu'il est utilisé dans la macro développée, ce qui n'est généralement pas ce que nous voulons. Cela est vrai même si la macro renferme les paramètres entre parenthèses pour empêcher tout développement de la part de l'extension.

int oops = 5;
double incremental_damage = AREA(oops++);
// Compiler sees:
double incremental_damage = (3.14159265358979*(oops++)*(oops++));

En outre, les macros ne fournissent aucune sécurité de type, ce qui entraîne des erreurs difficiles à comprendre concernant la non-concordance de type.


Comme les programmeurs terminent normalement les lignes avec un point-virgule, les macros destinées à être utilisées comme lignes autonomes sont souvent conçues pour "avaler" un point-virgule; Cela évite que des bogues supplémentaires ne soient causés par un point-virgule supplémentaire.

#define IF_BREAKER(Func) Func();

if (some_condition)
    // Oops.
    IF_BREAKER(some_func);
else
    std::cout << "I am accidentally an orphan." << std::endl;

Dans cet exemple, le double point-virgule involontaire rompt le bloc if...else , empêchant le compilateur de faire correspondre le else au if . Pour éviter cela, le point-virgule est omis de la définition de la macro, ce qui le fera "avaler" le point-virgule immédiatement après son utilisation.

#define IF_FIXER(Func) Func()

if (some_condition)
    IF_FIXER(some_func);
else
    std::cout << "Hooray!  I work again!" << std::endl;

Laisser le point-virgule final permet également d'utiliser la macro sans mettre fin à l'instruction en cours, ce qui peut être bénéfique.

#define DO_SOMETHING(Func, Param) Func(Param, 2)

// ...

some_function(DO_SOMETHING(some_func, 3), DO_SOMETHING(some_func, 42));

Normalement, une définition de macro se termine à la fin de la ligne. Si une macro doit couvrir plusieurs lignes, une barre oblique inverse peut être utilisée à la fin d'une ligne pour indiquer cela. Cette barre oblique inverse doit être le dernier caractère de la ligne, ce qui indique au préprocesseur que la ligne suivante doit être concaténée sur la ligne en cours, en les traitant comme une seule ligne. Cela peut être utilisé plusieurs fois de suite.

#define TEXT "I \
am \
many \
lines."

// ...

std::cout << TEXT << std::endl; // Output:   I am many lines.

Ceci est particulièrement utile dans les macros complexes de type fonction, qui peuvent nécessiter plusieurs lignes.

#define CREATE_OUTPUT_AND_DELETE(Str) \
    std::string* tmp = new std::string(Str); \
    std::cout << *tmp << std::endl; \
    delete tmp;

// ...

CREATE_OUTPUT_AND_DELETE("There's no real need for this to use 'new'.")

Dans le cas de macros de type fonction plus complexes, il peut être utile de leur donner leur propre champ d'application pour empêcher les collisions de noms possibles ou pour provoquer la destruction d'objets à la fin de la macro, comme une fonction réelle. Un idiome commun pour cela est do tout en 0 , où la macro est entourée d'un bloc do-while . Ce bloc n'est généralement pas suivi d'un point-virgule, ce qui lui permet d'avaler un point-virgule.

#define DO_STUFF(Type, Param, ReturnVar) do { \
    Type temp(some_setup_values); \
    ReturnVar = temp.process(Param); \
} while (0)

int x;
DO_STUFF(MyClass, 41153.7, x);

// Compiler sees:

int x;
do {
    MyClass temp(some_setup_values);
    x = temp.process(41153.7);
} while (0);

Il existe également des macros variadiques; Tout comme les fonctions variadiques, elles prennent un nombre variable d'arguments, puis les développent toutes à la place d'un paramètre spécial "Varargs", __VA_ARGS__ .

#define VARIADIC(Param, ...) Param(__VA_ARGS__)

VARIADIC(printf, "%d", 8);
// Compiler sees:
printf("%d", 8);

Notez que lors de l'expansion, __VA_ARGS__ peut être placé n'importe où dans la définition et sera développé correctement.

#define VARIADIC2(POne, PTwo, PThree, ...) POne(PThree, __VA_ARGS__, PTwo)

VARIADIC2(some_func, 3, 8, 6, 9);
// Compiler sees:
some_func(8, 6, 9, 3);

Dans le cas d'un paramètre variadic à argument nul, différents compilateurs gèrent différemment la virgule finale. Certains compilateurs, tels que Visual Studio, avalent silencieusement la virgule sans aucune syntaxe particulière. D'autres compilateurs, tels que GCC, exigent que vous __VA_ARGS__ ## immédiatement avant __VA_ARGS__ . Pour cette raison, il est judicieux de définir de manière conditionnelle les macros variadiques lorsque la portabilité est un problème.

// In this example, COMPILER is a user-defined macro specifying the compiler being used.

#if       COMPILER == "VS"
    #define VARIADIC3(Name, Param, ...) Name(Param, __VA_ARGS__)
#elif     COMPILER == "GCC"
    #define VARIADIC3(Name, Param, ...) Name(Param, ##__VA_ARGS__)
#endif /* COMPILER */

Messages d'erreur de préprocesseur

Des erreurs de compilation peuvent être générées à l'aide du préprocesseur. Ceci est utile pour un certain nombre de raisons dont certaines incluent la notification à un utilisateur s’il se trouve sur une plate-forme non prise en charge ou un compilateur non pris en charge.

ex. Erreur de retour si la version de gcc est 3.0.0 ou antérieure.

#if __GNUC__ < 3
#error "This code requires gcc > 3.0.0"
#endif

par exemple, erreur de retour si compilation sur un ordinateur Apple.

#ifdef __APPLE__
#error "Apple products are not supported in this release"
#endif

Macros prédéfinies

Les macros prédéfinies sont celles que le compilateur définit (contrairement à ce que l'utilisateur définit dans le fichier source). Ces macros ne doivent pas être redéfinies ou indéfinies par l'utilisateur.

Les macros suivantes sont prédéfinies par le standard C ++:

  • __LINE__ contient le numéro de ligne de la ligne sur laquelle cette macro est utilisée et peut être modifié par la directive #line .
  • __FILE__ contient le nom du fichier dans __FILE__ cette macro est utilisée et peut être modifié par la directive #line .
  • __DATE__ contient la date (au format "Mmm dd yyyy" ) de la compilation du fichier, où Mmm est formaté comme s'il était obtenu par un appel à std::asctime() .
  • __TIME__ contient l'heure (au format "hh:mm:ss" ) de la compilation du fichier.
  • __cplusplus est défini par des compilateurs C ++ (conformes) lors de la compilation de fichiers C ++. Sa valeur est la version standard avec laquelle le compilateur est entièrement conforme, à savoir 199711L pour C ++ 98 et C ++ 03, 201103L pour C ++ 11 et 201402L pour le standard C ++ 14.
c ++ 11
  • __STDC_HOSTED__ est défini sur 1 si l'implémentation est hébergée ou 0 si elle est autonome .
c ++ 17
  • __STDCPP_DEFAULT_NEW_ALIGNMENT__ contient un littéral size_t , c'est-à-dire l'alignement utilisé pour un appel à un operator new alignement-ignorant.

De plus, les macros suivantes peuvent être prédéfinies par les implémentations et peuvent ou non être présentes:

  • __STDC__ a une signification dépendant de l'implémentation et est généralement définie uniquement lors de la compilation d'un fichier en C, pour indiquer la conformité totale au standard C. (Ou jamais, si le compilateur décide de ne pas supporter cette macro.)
c ++ 11
  • __STDC_VERSION__ a une signification dépendant de l'implémentation, et sa valeur est généralement la version C, de la même manière que __cplusplus est la version C ++. (Ou n'est même pas défini, si le compilateur décide de ne pas supporter cette macro.)
  • __STDC_MB_MIGHT_NEQ_WC__ est défini sur 1 , si les valeurs du codage étroit du jeu de caractères de base peuvent ne pas être égales aux valeurs de leurs homologues larges (par exemple if (uintmax_t)'x' != (uintmax_t)L'x' )
  • __STDC_ISO_10646__ est défini si wchar_t est codé en Unicode et se développe en une constante entière sous la forme yyyymmL , indiquant la dernière révision Unicode prise en charge.
  • __STDCPP_STRICT_POINTER_SAFETY__ est défini sur 1 si l'implémentation a une sécurité de pointeur stricte (sinon, la sécurité du pointeur est relâchée )
  • __STDCPP_THREADS__ est défini sur 1 , si le programme peut avoir plusieurs threads d'exécution (applicable aux implémentations autonomes - les implémentations hébergées peuvent toujours avoir plusieurs threads)

Il convient également de mentionner __func__ , qui n'est pas une macro, mais une variable fonction-locale prédéfinie. Il contient le nom de la fonction dans laquelle il est utilisé, en tant que tableau de caractères statiques dans un format défini par l'implémentation.

En plus de ces macros prédéfinies standard, les compilateurs peuvent avoir leur propre ensemble de macros prédéfinies. Il faut se référer à la documentation du compilateur pour les apprendre. Par exemple:

Certaines des macros sont juste pour interroger le support de certaines fonctionnalités:

#ifdef __cplusplus // if compiled by C++ compiler
extern "C"{ // C code has to be decorated
   // C library header declarations here
}
#endif

D'autres sont très utiles pour le débogage:

c ++ 11
bool success = doSomething( /*some arguments*/ );
if( !success ){
    std::cerr << "ERROR: doSomething() failed on line " << __LINE__ - 2
              << " in function " << __func__ << "()"
              << " in file " << __FILE__
              << std::endl;
}

Et d'autres pour le contrôle de version trivial:

int main( int argc, char *argv[] ){
    if( argc == 2 && std::string( argv[1] ) == "-v" ){
        std::cout << "Hello World program\n"
                  << "v 1.1\n" // I have to remember to update this manually
                  << "compiled: " << __DATE__ << ' ' << __TIME__ // this updates automagically
                  << std::endl;
    }
    else{
        std::cout << "Hello World!\n";
    }
}

X-macros

Une technique idiomatique pour générer des structures de code répétitives au moment de la compilation.

Une macro X se compose de deux parties: la liste et l'exécution de la liste.

Exemple:

#define LIST \
    X(dog)   \
    X(cat)   \
    X(racoon)

// class Animal {
//  public:
//    void say();
// };

#define X(name) Animal name;
LIST
#undef X

int main() {
#define X(name) name.say();
    LIST
#undef X

    return 0;
}

qui est développé par le préprocesseur dans les éléments suivants:

Animal dog;
Animal cat;
Animal racoon;

int main() {
    dog.say();
    cat.say();
    racoon.say();

    return 0;
}    

Comme les listes deviennent plus grandes (disons plus de 100 éléments), cette technique aide à éviter un copier-coller excessif.

Source: https://en.wikipedia.org/wiki/X_Macro

Voir aussi: Macros X


Si définir un X peu pertinent avant d'utiliser LIST n'est pas à votre goût, vous pouvez également passer un nom de macro en argument:

#define LIST(MACRO) \
    MACRO(dog) \
    MACRO(cat) \
    MACRO(racoon)

Maintenant, vous spécifiez explicitement quelle macro doit être utilisée lors du développement de la liste, par exemple

#define FORWARD_DECLARE_ANIMAL(name) Animal name;
LIST(FORWARD_DECLARE_ANIMAL)

Si chaque appel de la MACRO doit prendre des paramètres supplémentaires - constants par rapport à la liste, des macros variadic peuvent être utilisées

//a walkaround for Visual studio
#define EXPAND(x) x

#define LIST(MACRO, ...) \
    EXPAND(MACRO(dog, __VA_ARGS__)) \
    EXPAND(MACRO(cat, __VA_ARGS__)) \
    EXPAND(MACRO(racoon, __VA_ARGS__))

Le premier argument est fourni par la LIST , tandis que le reste est fourni par l'utilisateur dans l'appel de LIST . Par exemple:

#define FORWARD_DECLARE(name, type, prefix) type prefix##name;
LIST(FORWARD_DECLARE,Animal,anim_)
LIST(FORWARD_DECLARE,Object,obj_)

étendra à

Animal anim_dog;
Animal anim_cat;
Animal anim_racoon;
Object obj_dog;
Object obj_cat;
Object obj_racoon;        

#pragma une fois

La plupart des implémentations C ++, mais pas toutes, prennent en charge la directive #pragma once qui garantit que le fichier n'est inclus qu'une seule fois dans une seule compilation. Il ne fait partie d'aucune norme ISO C ++. Par exemple:

// Foo.h
#pragma once

class Foo
{
};

Alors que #pragma once évite certains problèmes associés aux gardes d'inclusion , un #pragma - par définition dans les standards - est intrinsèquement un hook spécifique au compilateur, et sera ignoré par les compilateurs qui ne le supportent pas. Les projets qui utilisent #pragma once doivent être modifiés pour être conformes aux normes.

Avec certains compilateurs, en particulier ceux qui utilisent des en - têtes précompilés , #pragma once peut, #pragma once accélérer considérablement le processus de compilation. De même, certains préprocesseurs accélèrent la compilation en suivant les en-têtes utilisés, notamment les gardes. L'avantage net, lorsque les deux #pragma once sont utilisées, dépend de l'implémentation et peut être une augmentation ou une diminution des temps de compilation.

#pragma once combiné avec les inclusions a été la mise en page recommandée pour les fichiers d' en- tête lors de l' écriture des applications MFC sur les fenêtres, et a été générée par de Visual Studio add class , add dialog , add windows des add windows assistants. Il est donc très courant de les trouver combinées dans les applications Windows C ++.

Opérateurs de préprocesseur

# opérateur ou opérateur de chaîne est utilisé pour convertir un paramètre de macro en un littéral de chaîne. Il ne peut être utilisé qu'avec les macros ayant des arguments.

// preprocessor will convert the parameter x to the string literal x
#define PRINT(x) printf(#x "\n")

PRINT(This line will be converted to string by preprocessor);
// Compiler sees
printf("This line will be converted to string by preprocessor""\n");

Le compilateur concatène deux chaînes et l'argument final printf() sera un littéral de chaîne avec un caractère de nouvelle ligne à sa fin.

Le préprocesseur ignore les espaces avant ou après l'argument de macro. Donc, la déclaration imprimée ci-dessous nous donnera le même résultat.

PRINT(   This line will be converted to string by preprocessor );

Si le paramètre du littéral de chaîne nécessite une séquence d'échappement comme avant un guillemet double (), il sera automatiquement inséré par le préprocesseur.

PRINT(This "line" will be converted to "string" by preprocessor); 
// Compiler sees
printf("This \"line\" will be converted to \"string\" by preprocessor""\n");

## operator ou Token pasting operator permet de concaténer deux paramètres ou jetons d'une macro.

// preprocessor will combine the variable and the x
#define PRINT(x) printf("variable" #x " = %d", variable##x)

int variableY = 15;
PRINT(Y);
//compiler sees
printf("variable""Y"" = %d", variableY);

et le résultat final sera

variableY = 15


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow