Movatterモバイル変換


[0]ホーム

URL:


igraph Reference Manual

For using the igraph C library

Search the manual:

Chapter 5. Error handling

1.  Error handling basics

igraph functions can run into various problems preventing themfrom normal operation. The user might have supplied invalid arguments,e.g. a non-square matrix when a square-matrix was expected, or the programhas run out of memory while some more memory allocation is required, etc.

By defaultigraph aborts the program when it runs into anerror. While this behavior might be good enough for smaller programs,it is without doubt avoidable in larger projects. Please read furtherif your project requires more sophisticated error handling. You cansafely skip the rest of this chapter otherwise.

2.  Error handlers

Ifigraph runs into an error - an invalid argument was suppliedto a function, or we've ran out of memory - the control istransferred to the error handler function.

The default error handler isigraph_error_handler_abort whichprints an error message and aborts the program.

Theigraph_set_error_handler() function can be used to set a newerror handler function of typeigraph_error_handler_t; see thedocumentation of this type for details.

There are two other predefined error handler functions,igraph_error_handler_ignore andigraph_error_handler_printignore.These deallocate the temporarily allocated memory (more about thislater) and return with the error code. The latter also prints anerror message. If you use these error handlers you need to takecare about possible errors yourself by checking the return value of(almost) every non-voidigraph function.

Independently of the error handler installed, all functions in thelibrary do their best to leave their argumentssemantically unchanged if an errorhappens. By semantically we mean that the implementation of anobject supplied as an argument might change, but itsmeaning in most cases does not. The rare occasionswhen this rule is violated are documented in this manual.

2.1. igraph_error_handler_t — The type of error handler functions.

typedef void igraph_error_handler_t(const char *reason, const char *file,                                    int line, igraph_error_t igraph_errno);

This is the type of the error handler functions.

Arguments: 

reason:

Textual description of the error.

file:

The source file in which the error is noticed.

line:

The number of the line in the source file which triggered the error

igraph_errno:

Theigraph error code.

2.2. igraph_error_handler_abort — Abort program in case of error.

IGRAPH_FUNCATTR_NORETURN igraph_error_handler_t igraph_error_handler_abort;

The default error handler, prints an error message and aborts theprogram.

2.3. igraph_error_handler_ignore — Ignore errors.

igraph_error_handler_t igraph_error_handler_ignore;

This error handler frees the temporarily allocated memory and returnswith the error code.

2.4. igraph_error_handler_printignore — Print and ignore errors.

igraph_error_handler_t igraph_error_handler_printignore;

Frees temporarily allocated memory, prints an error message to thestandard error and returns with the error code.

3.  Error codes

Everyigraph function which can fail return asingle integer error code. Some functions are very simple andcannot run into any error, these may return other types, orvoid as well. The error codes are defined by theigraph_error_type_t enumeration.

3.1. igraph_error_t — Return type for functions returning an error code.

typedef igraph_error_type_t igraph_error_t;

This type is used as the return type of igraph functions that return anerror code. It is a type alias becauseigraph_error_t used to beanint, and was used slightly differenly thanigraph_error_type_t.

3.2. igraph_error_type_t — Error code type.

typedef enum {    IGRAPH_SUCCESS           = 0,    IGRAPH_FAILURE           = 1,    IGRAPH_ENOMEM            = 2,    IGRAPH_PARSEERROR        = 3,    IGRAPH_EINVAL            = 4,    IGRAPH_EXISTS            = 5,    IGRAPH_EINVEVECTOR       = 6,    IGRAPH_EINVVID           = 7,    IGRAPH_NONSQUARE         = 8,    IGRAPH_EINVMODE          = 9,    IGRAPH_EFILE             = 10,    IGRAPH_UNIMPLEMENTED     = 12,    IGRAPH_INTERRUPTED       = 13,    IGRAPH_DIVERGED          = 14,    IGRAPH_ARPACK_PROD       = 15,   /* unused, reserved */    IGRAPH_ARPACK_NPOS       = 16,    IGRAPH_ARPACK_NEVNPOS    = 17,    IGRAPH_ARPACK_NCVSMALL   = 18,    IGRAPH_ARPACK_NONPOSI    = 19,    IGRAPH_ARPACK_WHICHINV   = 20,    IGRAPH_ARPACK_BMATINV    = 21,    IGRAPH_ARPACK_WORKLSMALL = 22,    IGRAPH_ARPACK_TRIDERR    = 23,    IGRAPH_ARPACK_ZEROSTART  = 24,    IGRAPH_ARPACK_MODEINV    = 25,    IGRAPH_ARPACK_MODEBMAT   = 26,    IGRAPH_ARPACK_ISHIFT     = 27,    IGRAPH_ARPACK_NEVBE      = 28,    IGRAPH_ARPACK_NOFACT     = 29,    IGRAPH_ARPACK_FAILED     = 30,    IGRAPH_ARPACK_HOWMNY     = 31,    IGRAPH_ARPACK_HOWMNYS    = 32,    IGRAPH_ARPACK_EVDIFF     = 33,    IGRAPH_ARPACK_SHUR       = 34,    IGRAPH_ARPACK_LAPACK     = 35,    IGRAPH_ARPACK_UNKNOWN    = 36,    IGRAPH_ENEGCYCLE         = 37,    IGRAPH_ENEGLOOP IGRAPH_DEPRECATED_ENUMVAL = IGRAPH_ENEGCYCLE,    IGRAPH_EINTERNAL         = 38,    IGRAPH_ARPACK_MAXIT      = 39,    IGRAPH_ARPACK_NOSHIFT    = 40,    IGRAPH_ARPACK_REORDER    = 41,    IGRAPH_EDIVZERO          = 42,    IGRAPH_GLP_EBOUND        = 43,    IGRAPH_GLP_EROOT         = 44,    IGRAPH_GLP_ENOPFS        = 45,    IGRAPH_GLP_ENODFS        = 46,    IGRAPH_GLP_EFAIL         = 47,    IGRAPH_GLP_EMIPGAP       = 48,    IGRAPH_GLP_ETMLIM        = 49,    IGRAPH_GLP_ESTOP         = 50,    IGRAPH_EATTRIBUTES       = 51,    IGRAPH_EATTRCOMBINE      = 52,    IGRAPH_ELAPACK           = 53,    IGRAPH_EDRL IGRAPH_DEPRECATED_ENUMVAL = 54,    IGRAPH_EOVERFLOW         = 55,    IGRAPH_EGLP              = 56,    IGRAPH_CPUTIME           = 57,    IGRAPH_EUNDERFLOW        = 58,    IGRAPH_ERWSTUCK          = 59,    IGRAPH_STOP              = 60,    IGRAPH_ERANGE            = 61,    IGRAPH_ENOSOL            = 62} igraph_error_type_t;

These are the possible values returned byigraph functions.Note that these are interesting only if you defined an error handlerwithigraph_set_error_handler(). Otherwise the program is abortedand the function causing the error never returns.

Values: 

IGRAPH_SUCCESS:

The function successfully completed its task.

IGRAPH_FAILURE:

Something went wrong. You'll almost never meet this error as normally more specific error codes are used.

IGRAPH_ENOMEM:

There wasn't enough memory to allocate on the heap.

IGRAPH_PARSEERROR:

A parse error was found in a file.

IGRAPH_EINVAL:

A parameter's value is invalid. E.g. negative number was specified as the number of vertices.

IGRAPH_EXISTS:

A graph/vertex/edge attribute is already installed with the given name.

IGRAPH_EINVEVECTOR:

Invalid vector of vertex IDs. A vertex ID is either negative or bigger than the number of vertices minus one.

IGRAPH_EINVVID:

Invalid vertex ID, negative or too big.

IGRAPH_NONSQUARE:

A non-square matrix was received while a square matrix was expected.

IGRAPH_EINVMODE:

Invalid mode parameter.

IGRAPH_EFILE:

A file operation failed. E.g. a file doesn't exist, or the user has no rights to open it.

IGRAPH_UNIMPLEMENTED:

Attempted to call an unimplemented or disabled (at compile-time) function.

IGRAPH_DIVERGED:

A numeric algorithm failed to converge.

IGRAPH_ARPACK_PROD:

Matrix-vector product failed (not used any more).

IGRAPH_ARPACK_NPOS:

N must be positive.

IGRAPH_ARPACK_NEVNPOS:

NEV must be positive.

IGRAPH_ARPACK_NCVSMALL:

NCV must be bigger.

IGRAPH_ARPACK_NONPOSI:

Maximum number of iterations should be positive.

IGRAPH_ARPACK_WHICHINV:

Invalid WHICH parameter.

IGRAPH_ARPACK_BMATINV:

Invalid BMAT parameter.

IGRAPH_ARPACK_WORKLSMALL:

WORKL is too small.

IGRAPH_ARPACK_TRIDERR:

LAPACK error in tridiagonal eigenvalue calculation.

IGRAPH_ARPACK_ZEROSTART:

Starting vector is zero.

IGRAPH_ARPACK_MODEINV:

MODE is invalid.

IGRAPH_ARPACK_MODEBMAT:

MODE and BMAT are not compatible.

IGRAPH_ARPACK_ISHIFT:

ISHIFT must be 0 or 1.

IGRAPH_ARPACK_NEVBE:

NEV and WHICH='BE' are incompatible.

IGRAPH_ARPACK_NOFACT:

Could not build an Arnoldi factorization.

IGRAPH_ARPACK_FAILED:

No eigenvalues to sufficient accuracy.

IGRAPH_ARPACK_HOWMNY:

HOWMNY is invalid.

IGRAPH_ARPACK_HOWMNYS:

HOWMNY='S' is not implemented.

IGRAPH_ARPACK_EVDIFF:

Different number of converged Ritz values.

IGRAPH_ARPACK_SHUR:

Error from calculation of a real Schur form.

IGRAPH_ARPACK_LAPACK:

LAPACK (dtrevc) error for calculating eigenvectors.

IGRAPH_ARPACK_UNKNOWN:

Unknown ARPACK error.

IGRAPH_ENEGCYCLE:

Negative cycle detected while calculating shortest paths.

IGRAPH_EINTERNAL:

Internal error, likely a bug in igraph.

IGRAPH_EDIVZERO:

Big integer division by zero.

IGRAPH_GLP_EBOUND:

GLPK error (GLP_EBOUND).

IGRAPH_GLP_EROOT:

GLPK error (GLP_EROOT).

IGRAPH_GLP_ENOPFS:

GLPK error (GLP_ENOPFS).

IGRAPH_GLP_ENODFS:

GLPK error (GLP_ENODFS).

IGRAPH_GLP_EFAIL:

GLPK error (GLP_EFAIL).

IGRAPH_GLP_EMIPGAP:

GLPK error (GLP_EMIPGAP).

IGRAPH_GLP_ETMLIM:

GLPK error (GLP_ETMLIM).

IGRAPH_GLP_ESTOP:

GLPK error (GLP_ESTOP).

IGRAPH_EATTRIBUTES:

Attribute handler error. The user is not expected to find this; it is signalled if some igraph function is not using the attribute handler interface properly.

IGRAPH_EATTRCOMBINE:

Unimplemented attribute combination method for the given attribute type.

IGRAPH_ELAPACK:

A LAPACK call resulted in an error.

IGRAPH_EDRL:

Internal error in the DrL layout generator; not used any more (replaced by IGRAPH_EINTERNAL).

IGRAPH_EOVERFLOW:

Integer or double overflow.

IGRAPH_EGLP:

Internal GLPK error.

IGRAPH_CPUTIME:

CPU time exceeded.

IGRAPH_EUNDERFLOW:

Integer or double underflow.

IGRAPH_ERWSTUCK:

Random walk got stuck.

IGRAPH_ERANGE:

Maximum vertex or edge count exceeded.

IGRAPH_ENOSOL:

Input problem has no solution.

3.3. igraph_strerror — Textual description of an error.

const char *igraph_strerror(const igraph_error_t igraph_errno);

This is a simple utility function, it gives a short general textualdescription for anigraph error code.

Arguments: 

igraph_errno:

Theigraph error code.

Returns: 

pointer to the textual description of the error code.

4.  Warning messages

igraph also supports warning messages in addition to errormessages. Warning messages typically do not terminate theprogram, but they are usually crucial to the user.

igraph warnings are handled similarly to errors. There is aseparate warning handler function that is called wheneveranigraph function triggers a warning. This handler can beset by theigraph_set_warning_handler() function. There aretwo predefined simple warning handlers,igraph_warning_handler_ignore() andigraph_warning_handler_print(), the latter being the default.

To trigger a warning,igraph functions typically use theIGRAPH_WARNING() macro, theigraph_warning() function,or if more flexibility is needed,igraph_warningf().

4.1. igraph_warning_handler_t — The type of igraph warning handler functions.

typedef void igraph_warning_handler_t(const char *reason,                                      const char *file, int line);

Currently it is defined to have the same type asigraph_error_handler_t, although the last (error code)argument is not used.

4.2. igraph_set_warning_handler — Installs a warning handler.

igraph_warning_handler_t *igraph_set_warning_handler(igraph_warning_handler_t *new_handler);

Install the supplied warning handler function.

Arguments: 

new_handler:

The new warning handler function to install. Supply a null pointer here to uninstall the current warning handler, without installing a new one.

Returns: 

The current warning handler function.

4.3. IGRAPH_WARNING — Triggers a warning.

#define IGRAPH_WARNING(reason)

This is the usual way of triggering a warning from an igraphfunction. It callsigraph_warning().

Arguments: 

reason:

The warning message.

4.4. IGRAPH_WARNINGF — Triggers a warning, with printf-like syntax.

#define IGRAPH_WARNINGF(reason, ...)

igraph functions can use this macro when they notice a warning andwant to pass on extra information to the user about what went wrong.It callsigraph_warningf() with the proper parameters and noerror code.

Arguments: 

reason:

Textual description of the warning, a template string with the same syntax as the standard printf C library function.

...:

The additional arguments to be substituted into the template string.

4.5. igraph_warning — Reports a warning.

void igraph_warning(const char *reason, const char *file, int line);

Call this function if you want to trigger a warning from withina function that usesigraph.

Arguments: 

reason:

Textual description of the warning.

file:

The source file in which the warning was noticed.

line:

The number of line in the source file which triggered the warning.

4.6. igraph_warningf — Reports a warning, printf-like version.

void igraph_warningf(const char *reason, const char *file, int line, ...);

This function is similar toigraph_warning(), butuses a printf-like syntax. It substitutes the additional argumentsinto thereason template string and callsigraph_warning().

Arguments: 

reason:

Textual description of the warning, a template string with the same syntax as the standard printf C library function.

file:

The source file in which the warning was noticed.

line:

The number of line in the source file which triggered the warning.

...:

The additional arguments to be substituted into the template string.

4.7. igraph_warning_handler_ignore — Ignores all warnings.

void igraph_warning_handler_ignore(const char *reason, const char *file, int line);

This warning handler function simply ignores all warnings.

Arguments: 

reason:

Textual description of the warning.

file:

The source file in which the warning was noticed.

line:

The number of line in the source file which triggered the warning..

4.8. igraph_warning_handler_print — Prints all warnings to the standard error.

void igraph_warning_handler_print(const char *reason, const char *file, int line);

This warning handler function simply prints all warnings to thestandard error.

Arguments: 

reason:

Textual description of the warning.

file:

The source file in which the warning was noticed.

line:

The number of line in the source file which triggered the warning..

5. Advanced topics

5.1.  Writing error handlers

The contents of the rest of this chapter might be useful onlyfor those who want to create an interface toigraph from anotherlanguage, or use igraph from a GUI application. Most readers cansafely skip to the next chapter.

You can write and install error handlers simply by defining afunction of typeigraph_error_handler_t and callingigraph_set_error_handler(). This feature is useful for interfacewriters, asigraph will have the chance tosignal errors the appropriate way. For example, the R interface usesR's native printing facilities to communicate errors, while the Pythoninterface converts them into Python exceptions.

The two main tasks of the error handler are to report the error(i.e. print the error message) and ensure proper resource cleanup.This is ensured by callingIGRAPH_FINALLY_FREE(), which deallocatessome of the temporary memory to avoid memory leaks. Note that this mayinvalidate the error message bufferreason passed to the error handler.Do not access it after having calledIGRAPH_FINALLY_FREE().

As ofigraph 0.10, temporary memory is dellocated in stages, throughmultiple calls to the error handler (and indirectly toIGRAPH_FINALLY_FREE()).Therefore, error handlers that do not abort the programimmediately are expected to return. The error handler should not performalongjmp, as this may lead to some of the memory notgetting freed.

5.1.1. igraph_set_error_handler — Sets a new error handler.

igraph_error_handler_t *igraph_set_error_handler(igraph_error_handler_t *new_handler);

Installs a new error handler. If called withNULL, it installs thedefault error handler (which is currentlyigraph_error_handler_abort).

Arguments: 

new_handler:

The error handler function to install.

Returns: 

The old error handler function. This should be saved and restored ifnew_handler is not needed any more.

5.2.  Error handling internals

If an error happens, the functions in the library call theIGRAPH_ERROR() macro with a textual description of the error and anigraph error code. This macro calls (through theigraph_error() function) the installed error handler. Another usefulmacro isIGRAPH_CHECK(). This checks the return value of itsargument, which is normally a function call, and callsIGRAPH_ERROR() if it is notIGRAPH_SUCCESS.

5.2.1. IGRAPH_ERROR — Triggers an error.

#define IGRAPH_ERROR(reason, igraph_errno)

igraph functions usually use this macro when they notice an error.It callsigraph_error() with the proper parameters and if that returnsthe macro returns the "calling" function as well, with the errorcode. If for some (suspicious) reason you want to call the errorhandler without returning from the current function, calligraph_error() directly.

Arguments: 

reason:

Textual description of the error. This should be something more descriptive than the text associated with the error code. E.g. if the error code isIGRAPH_EINVAL, its associated text (seeigraph_strerror()) is "Invalid value" and this string should explain which parameter was invalid and maybe why.

igraph_errno:

Theigraph error code.

5.2.2. IGRAPH_ERRORF — Triggers an error, with printf-like syntax.

#define IGRAPH_ERRORF(reason, igraph_errno, ...)

igraph functions can use this macro when they notice an error andwant to pass on extra information to the user about what went wrong.It callsigraph_errorf() with the proper parameters and if thatreturns the macro returns the "calling" function as well, with theerror code. If for some (suspicious) reason you want to call theerror handler without returning from the current function, calligraph_errorf() directly.

Arguments: 

reason:

Textual description of the error, a template string with the same syntax as the standard printf C library function. This should be something more descriptive than the text associated with the error code. E.g. if the error code isIGRAPH_EINVAL, its associated text (seeigraph_strerror()) is "Invalid value" and this string should explain which parameter was invalid and maybe what was expected and what was recieved.

igraph_errno:

Theigraph error code.

...:

The additional arguments to be substituted into the template string.

5.2.3. igraph_error — Reports an error.

igraph_error_t igraph_error(const char *reason, const char *file, int line,                            igraph_error_t igraph_errno);

igraph functions usually call this function (most often via theIGRAPH_ERROR macro) if they notice an error.It calls the currently installed error handler function with thesupplied arguments.

Arguments: 

reason:

Textual description of the error.

file:

The source file in which the error was noticed.

line:

The number of line in the source file which triggered the error.

igraph_errno:

Theigraph error code.

Returns: 

The error code (if it returns).

See also: 

5.2.4. igraph_errorf — Reports an error, printf-like version.

igraph_error_t igraph_errorf(const char *reason, const char *file, int line,                             igraph_error_t igraph_errno, ...);

Arguments: 

reason:

Textual description of the error, interpreted as aprintf format string.

file:

The source file in which the error was noticed.

line:

The line in the source file which triggered the error.

igraph_errno:

Theigraph error code.

...:

Additional parameters, the values to substitute into the format string.

Returns: 

The error code (if it returns).

See also: 

5.2.5. IGRAPH_CHECK — Checks the return value of a function call.

#define IGRAPH_CHECK(expr)

Arguments: 

expr:

An expression, usually a function call. It is guaranteed tobe evaluated only once.

Executes the expression and checks its value. If this is notIGRAPH_SUCCESS, it callsIGRAPH_ERROR withthe value as the error code. Here is an example usage:

 IGRAPH_CHECK(vector_push_back(&v, 100));

There is only one reason to use this macro when writingigraph functions. If the user installs an error handler whichreturns to the auxiliary calling code (likeigraph_error_handler_ignore andigraph_error_handler_printignore), and theigraph functionsignalling the error is called from anotherigraph functionthen we need to make sure that the error is propagated back tothe auxiliary (i.e. non-igraph) calling function. This is achievedby usingIGRAPH_CHECK on everyigraphcall which can return an error code.

5.2.6. IGRAPH_CHECK_CALLBACK — Checks the return value of a callback.

#define IGRAPH_CHECK_CALLBACK(expr, code)

Identical toIGRAPH_CHECK, but treatsIGRAPH_STOP as a normal(non-erroneous) return code. This macro is used in some igraph functionsthat allow the user to hook into a long-running calculation with a callbackfunction. When the user-defined callback function returnsIGRAPH_SUCCESS,the calculation will proceed normally. ReturningIGRAPH_STOP from thecallback will terminate the calculation without reporting an error. Returningany other value from the callback is treated as an error code, and igraphwill trigger the necessary cleanup functions before exiting the function.

Note thatIGRAPH_CHECK_CALLBACK does not handleIGRAPH_STOP by anymeans except returning it in the variable pointed to bycode. It is theresponsibility of the caller to handleIGRAPH_STOP accordingly.

Arguments: 

expr:

An expression, usually a call to a user-defined callback function.It is guaranteed to be evaluated only once.

code:

Pointer to an optional variable of typeigraph_error_t;the value of this variable will be set to the error code if it is not a nullpointer.

5.3.  Deallocating memory

If a function runs into an error (and the program is not aborted)the error handler should deallocate all temporary memory. This isdone by storing the address and the destroy function of all temporaryobjects in a stack. TheIGRAPH_FINALLY function declares an object astemporary by placing its address in the stack. If anigraph function returnswith success it callsIGRAPH_FINALLY_CLEAN() with thenumber of objects to remove from the stack. If an error happenshowever, the error handler should callIGRAPH_FINALLY_FREE() todeallocate each object added to the stack. This means that thetemporary objects allocated in the calling function (and etc.) willbe freed as well.

5.3.1. IGRAPH_FINALLY — Registers an object for deallocation.

#define IGRAPH_FINALLY(func, ptr)

This macro places the address of an object, together with theaddress of its destructor on a stack. This stack is used if anerror happens to deallocate temporarily allocated objects toprevent memory leaks. After manual deallocation, objects are removedfrom the stack usingIGRAPH_FINALLY_CLEAN().

The typical usage is just after an initialization:

IGRAPH_CHECK(igraph_vector_init(&vector, 0));IGRAPH_FINALLY(igraph_vector_destroy, &vector);

The most commonly used data structures, such asigraph_vector_t,have associated convenience macros that initialize the object and registerit on this stack in one step. Thus the pattern above can be replaced with asingle line:

IGRAPH_VECTOR_INIT_FINALLY(&vector, 0);

Arguments: 

func:

The function which is normally called to destroy the object.

ptr:

Pointer to the object itself.

5.3.2. IGRAPH_FINALLY_CLEAN — Signals clean deallocation of objects.

void IGRAPH_FINALLY_CLEAN(int num);

Removes the specified number of objects from the stack oftemporarily allocated objects. It is typically calledimmediately after manually destroying the objects:

igraph_vector_t vector;igraph_vector_init(&vector, 10);IGRAPH_FINALLY(igraph_vector_destroy, &vector);// use vectorigraph_vector_destroy(&vector);IGRAPH_FINALLY_CLEAN(1);

Arguments: 

num:

The number of objects to remove from the bookkeeping stack.

5.3.3. IGRAPH_FINALLY_FREE — Deallocates objects registered at the current level.

void IGRAPH_FINALLY_FREE(void);

Calls the destroy function for all objects in the current levelof the stack of temporarily allocated objects, i.e. up to thenearest mark set byIGRAPH_FINALLY_ENTER().This function must only be called from an error handler.It isnot appropriate to use itinstead of destroying each unneeded object of a function, as itdestroys the temporary objects of the caller function (and so on)as well.

5.4.  Writingigraph functions withproper error handling

There are some simple rules to keep in order to have functionsbehaving well in erroneous situations. First, check the argumentsof the functions and callIGRAPH_ERROR() if they are invalid. Second,callIGRAPH_FINALLY on each dynamically allocated object and callIGRAPH_FINALLY_CLEAN() with the proper argument before returning. Third, useIGRAPH_CHECK on alligraph function calls which can generate errors.

The size of the stack used for this bookkeeping is fixed, andsmall. If you want to allocate several objects, write a destroyfunction which can deallocate all of these. See theadjlist.c file in theigraph source for an example.

For some functions these mechanisms are simply not flexibleenough. These functions should define their own error handlers andrestore the error handler before they return.

Example 5.1.  Fileexamples/simple/igraph_contract_vertices.c

#include <igraph.h>/* Create the condensation of a directed graph. * Seehttps://en.wikipedia.org/wiki/Strongly_connected_component#Definitions * This example demonstrates how to write a basic igraph function, complete * with error handling. */igraph_error_tcondensation(const igraph_t *graph, igraph_t *cond) {    igraph_vector_int_t membership;/* Data structures such as vector must be initialized in igraph before use. */IGRAPH_CHECK(igraph_vector_int_init(&membership, 0));/* Adding the initialized vector to the "finally" stack ensures that it will     * be automatically destroyed if an error occurs. */IGRAPH_FINALLY(igraph_vector_int_destroy, &membership);/* Functions that return an error code can be wrapped in IGRAPH_CHECK to pass that error     * up to the caller. */IGRAPH_CHECK(igraph_connected_components(graph, &membership,/* csize */ NULL,/* no */ NULL, IGRAPH_STRONG));/* To compute the condensation, we simply contract strongly connected components.     * Since igraph_contract_vertices() modifies graphs in-place, we make a copy first. */IGRAPH_CHECK(igraph_copy(cond, graph));/* Since we are not done creating the condensation yet, we add 'cond' to the     * "finally" stack, so that it will be destroyed if an error occurs. */IGRAPH_FINALLY(igraph_destroy, cond);/* Contract strongly connected components. */IGRAPH_CHECK(igraph_contract_vertices(cond, &membership, NULL));/* igraph_contract_vertices() preserves all edges, some of which become     * parallel edges or self-loops after the contraction. We simplify these. */IGRAPH_CHECK(igraph_simplify(cond,/* remove_multiple */ true,/* remove_loops */ true, NULL));/* Data structures that are no longer needed must be explicitly destroyed.     * If they were added to the "finally" stack, they must be removed explicitly,     * in the opposite order to how they were added. IGRAPH_FINALLY_CLEAN removes     * the indicated number of entries from the "finally" stack. We remove     * 'membership' because it was destroyed, and 'cond' because the responsibility     * to destroy it is now with the caller. */igraph_vector_int_destroy(&membership);IGRAPH_FINALLY_CLEAN(2);return IGRAPH_SUCCESS;/* return with no error */}intmain(void) {    igraph_t graph, cond;/* Create a random directed graph with mean degree 2 and compute its condensation. */igraph_erdos_renyi_game_gnm(&graph, 100, 200, IGRAPH_DIRECTED, IGRAPH_NO_LOOPS);condensation(&graph, &cond);printf("Number of vertices in the condensation: %" IGRAPH_PRId "\n",igraph_vcount(&cond));igraph_write_graph_edgelist(&cond, stdout);/* Destroy data structures that are no longer needed. */igraph_destroy(&graph);igraph_destroy(&cond);return 0;}


5.5.  Fatal errors

In some rare situations,igraph may encounter an internal errorthat cannot be fully handled. In this case, it will call thecurrent fatal error handler. The default fatal error handlersimply prints the error and aborts the program.

Fatal error handlers do not return. Typically, they might abort thethe program immediately, or in the case of the high-leveligraphinterfaces, they might return to the top level using alongjmp(). The fatal error handler is only called whena serious error has occurred, and as a result igraph may be in aninconsistent state. The purpose of returning to the top level is togive the user a chance to save their work instead of aborting immediately.However, the program session should be restarted as soon as possible.

Most projects that useigraph will use the default fatal errorhandler.

5.5.1. igraph_fatal_handler_t — The type of igraph fatal error handler functions.

typedef void igraph_fatal_handler_t(const char *reason, const char *file, int line);

Functions of this typemust not return. Typically theycallabort() or do alongjmp().

Arguments: 

reason:

Textual description of the error.

file:

The source file in which the error is noticed.

line:

The number of the line in the source file which triggered the error.

5.5.2. igraph_set_fatal_handler — Installs a fatal error handler.

igraph_fatal_handler_t *igraph_set_fatal_handler(igraph_fatal_handler_t *new_handler);

Installs the supplied fatal error handler function.

Fatal error handler functionsmust not return. Typically, the fatalerror handler would either callabort() orlongjmp().

Arguments: 

new_handler:

The new fatal error handler function to install. Supply a null pointer here to uninstall the current fatal error handler, without installing a new one.

Returns: 

The current fatal error handler function.

5.5.3. igraph_fatal_handler_abort — Abort program in case of fatal error.

IGRAPH_FUNCATTR_NORETURN igraph_fatal_handler_t igraph_fatal_handler_abort;

The default fatal error handler, prints an error message and aborts the program.

5.5.4. IGRAPH_FATAL — Triggers a fatal error.

#define IGRAPH_FATAL(reason)

This is the usual way of triggering a fatal error from an igraphfunction. It callsigraph_fatal().

Use this macro only in situations where the error cannot be handled.The normal way to handle errors isIGRAPH_ERROR().

Arguments: 

reason:

The error message.

5.5.5. IGRAPH_FATALF — Triggers a fatal error, with printf-like syntax.

#define IGRAPH_FATALF(reason, ...)

igraph functions can use this macro when a fatal error occurs andwant to pass on extra information to the user about what went wrong.It callsigraph_fatalf() with the proper parameters.

Arguments: 

reason:

Textual description of the error, a template string with the same syntax as the standard printf C library function.

...:

The additional arguments to be substituted into the template string.

5.5.6. IGRAPH_ASSERT — igraph-specific replacement forassert().

#define IGRAPH_ASSERT(condition)

This macro is like the standardassert(), but instead ofcallingabort(), it callsigraph_fatal(). This allows for returningthe control to the calling program, e.g. returning to the top level in a high-leveligraph interface.

Unlikeassert(),IGRAPH_ASSERT() is not disabledwhen theNDEBUG macro is defined.

This macro is meant for internal use byigraph.

Since a typical fatal error handler does alongjmp(), avoid using thismacro in C++ code. With most compilers, destructor will not be called whenlongjmp() leaves the current scope.

Arguments: 

condition:

The condition to be checked.

5.5.7. igraph_fatal — Triggers a fatal error.

void igraph_fatal(const char *reason, const char *file, int line);

This function triggers a fatal error. Typically it is called indirectly throughIGRAPH_FATAL() orIGRAPH_ASSERT().

Arguments: 

reason:

Textual description of the error.

file:

The source file in which the error was noticed.

line:

The number of line in the source file which triggered the error.

5.5.8. igraph_fatalf — Triggers a fatal error, printf-like syntax.

void igraph_fatalf(const char *reason, const char *file, int line, ...);

This function is similar toigraph_fatal(), butuses a printf-like syntax. It substitutes the additional argumentsinto thereason template string and callsigraph_fatal().

Arguments: 

reason:

Textual description of the error.

file:

The source file in which the error was noticed.

line:

The number of line in the source file which triggered the error.

...:

The additional arguments to be substituted into the template string.

5.6.  Error handling and threads

It is likely that theigraph error handlingmethod isnot thread-safe, mainly because ofthe static global stack which is used to store the address of thetemporarily allocated objects. This issue might be addressed in alater version ofigraph.

← Chapter 4. Basic data types and interfaceChapter 6. Memory (de)allocation →

© 2003 – 2025 The igraph core team. • Code licensed under GNU GPL 2 or later, documentation underGNU FDL.


[8]ページ先頭

©2009-2025 Movatter.jp