[Home]

Summary:ASTERISK-23666: CLONE - nested functions aren't portable
Reporter:Diederik de Groot (dkdegroot)Labels:
Date Opened:2014-04-24 07:54:53Date Closed:2014-04-25 17:48:03
Priority:MajorRegression?Yes
Status:Closed/CompleteComponents:General
Versions:11.1.0 Frequency of
Occurrence
Constant
Related
Issues:
is the original version of this clone:ASTERISK-20850 [patch]Nested functions aren't portable. Adapting RAII_VAR to use clang/llvm blocks to get the same/similar functionality.
is related toASTERISK-20399 Compilation on some systems requires the -fnested-functions flag
Environment:CLANGAttachments:
Description:Nested functions are a GCC extension that is not sanctioned by C standards, thus the use of them is non-portable.  Specifically, CLANG does not support them.  CLANG is used by OSX, current versions of FreeBSD, and NetBSD is experimenting with it.  The RAII_VAR macro in include/asterisk/utils.h creates nested functions.  This prevents Asterisk 11.* from compiling with CLANG.
Comments:By: Diederik de Groot (dkdegroot) 2014-04-24 07:56:55.888-0500

Example of a possible clang solution (using blocks & cleanup):

===============================
#include <stdio.h>
#include <malloc.h>

#ifndef __has_feature
#define __has_feature(f) 0
#endif

#if __has_feature(blocks)
typedef void (^_raii_cleanup_block_t)(void);
static inline void _raii_cleanup_block(_raii_cleanup_block_t *b)
{ (*b)(); }

#define RAII_VAR(vartype, varname, initval, dtor) \
raii_cleanup_block_t _raii_cleanup ## varname __attribute_((cleanup(_raii_cleanup_block),unused)) = NULL; \
vartype varname = initval; \
_error_cleanup ## varname = ^
{ dtor(varname); }

#elif _GNUC_
#define RAII_VAR(vartype, varname, initval, dtor) \
auto void dtor ## varname (vartype * v); \
void dtor ## varname (vartype * v)
{ dtor(*v); }

\
vartype varname _attribute((cleanup(_dtor ## varname))) = (initval)
#else
#warning "Your compiler is not supported"
#endif

struct teststruct
{ int testA; char testB[10]; }

;

int main (void)
{ RAII_VAR(struct teststruct *, testvar, malloc(sizeof(struct teststruct)), free); testvar->testA=10; printf("testvar->testA: %d\n", testvar->testA); return 0; }

===============================
Compile using:
clang -fblocks
Or:
clang -fblocks -lBlocksRuntime

Can someone please look into this, and see if this is a viable solution. If it is, it would make clang/scan-build possible compilers for the asterisk project again. scan-build might actually be very helpfull.

By: Rusty Newton (rnewton) 2014-04-25 17:48:03.730-0500

Duplicate ASTERISK-20850. Closing this and reopening ASTERISK-20850 to make things easier to track. Plus people were watching the older issue that won't be watching the clone..