[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Reporting malloc failure in actions
From: |
Joe Nelson |
Subject: |
Re: Reporting malloc failure in actions |
Date: |
Wed, 30 Dec 2020 12:50:05 -0600 |
Christian Schoenebeck wrote:
> When it comes to error handling in Bison/Flex user actions, I would
> recommend to always define and use your own macros and/or functions in
> user actions instead of calling Bison/Flex ones directly. That safes
> you refactoring work over time.
Makes sense, I'll do that.
> #define PARSER_ALLOC(x) parser_alloc(x, #x)
Cool trick!
> static void* parser_alloc(size_t n, const char* expr) {
> if (!n) return NULL;
Oh good idea to check for zero size. POSIX says malloc() *might* return
NULL for zero size, which would then make us trigger a false
out-of-memory error.
https://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html#tag_16_311_04
"If size is 0, either a null pointer or a unique pointer that can be
successfully passed to free() shall be returned."
> void* p = malloc(n);
> if (!p) {
> fprintf(stderr, "Parser: malloc(%s) with size %zu failed.
> Aborting.\n",
> expr, n);
Might be more flexible to call yyerror() than printing directly to
stderr? Although the name of that function depends on api.prefix, and
its arguments depend on %param and %parse-param, so I'm not sure how our
general-purpose parser_alloc() would know what to do. Plus we'd have to
build the error string ourselves, which probably requires a malloc()...
> abort();
Rather than aborting, maybe we could do something like this
#ifdef YYNOMEM
/* newer bison version */
YYNOMEM;
#else
/* older bison (undocumented feature) */
goto yyexhaustedlab;
#endif
> }
> memset(p, 0, n);
What about using calloc() rather than the combination of malloc() and
memset()?