Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8488037
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 10, 20262026-06-10T21:25:10+00:00 2026-06-10T21:25:10+00:00

Is it possible to write portable C code using nested functions/blocks? I understand that

  • 0

Is it possible to write portable C code using nested functions/blocks?

I understand that gcc only supports nested functions as an non-standard extension, and clang only supports blocks – but is there a way to write code that will compile on both using standard C with MACROS?

If it is not possible – what is the best work around? As an example, how would one implement a portable version of the following sort that takes a parameter? Trivial example in GCC:

int main(int argc, char*[] argv)
{
  char reverse = 0;

  int cmp_func(const void *a, const void *b)
  {
    const int* aa = (const int)a;
    const int* bb = (const int)b;
    return (reverse) ? aa - bb : bb - aa;
  }

  int list[8] = {1,2,3,4,5,20,100,200};
  qsort(list, 8, sizeof(int), &cmp_func);
}

A similar example could be put together using Blocks in Clang. Ideally the solution should be thread-safe (so avoid global variables).

Edit: For clarity, lets assume “standard” means C99. The above is a trivial example. What I’m after is a C99 approach to a sort that requires some parameters. Here it just uses a char as a boolean, but I’m after a solution that would take multiple integers etc. It looks like this might not be possible without global variables.

Edit 2: I realised that passing a void pointer along with a function pointer enables you to do everything that can be done with nested functions. Thanks to @Quuxplusone for suggesting qsort_r and qsort_s. I’ve tried to put together a portable wrapper on qsort_r and qsort_s. It takes a comparator function and a void pointer to store state in, thus removing the dependency on nested functions for intricate sorting algorithms — so you can compile with both GCC and Clang.

typedef struct
{
  void *arg;
  int (*compar)(const void *a1, const void *a2, void *aarg);
} SortStruct;

int cmp_switch(void *s, const void *aa, const void *bb)
{
  SortStruct *ss = (SortStruct*)s;
  return (ss->compar)(aa, bb, ss->arg);
}

void sort_r(void *base, size_t nel, size_t width,
            int (*compar)(const void *a1, const void *a2, void *aarg), void *arg)
{
  #if (defined _GNU_SOURCE || defined __GNU__ || defined __linux__)

    qsort_r(base, nel, width, compar, arg);

  #elif (defined __APPLE__ || defined __MACH__ || defined __DARWIN__ || \
         defined __FREEBSD__ || defined __BSD__ || \
         defined OpenBSD3_1 || defined OpenBSD3_9)

    SortStruct tmp = {arg, compar};
    qsort_r(base, nel, width, &tmp, &cmp_switch);

  #elif (defined _WIN32 || defined _WIN64 || defined __WINDOWS__)

    SortStruct tmp = {arg, compar};
    qsort_s(*base, nel, width, &cmp_switch, &tmp);

  #else
    #error Cannot detect operating system
  #endif
}

Note: I haven’t tested this on many platforms, so please let me know if you see a bug / this doesn’t work on your machine.

As an example of usage, I’ve implemented the same sort as in the chosen answer:

int sort_r_cmp(const void *aa, const void *bb, void *arg)
{
  const int *a = aa, *b = bb, *p = arg;
  int cmp = *a - *b;
  int inv_start = p[0], inv_end = p[1];
  char norm = (*a < inv_start || *a > inv_end || *b < inv_start || *b > inv_end);

  return norm ? cmp : -cmp;
}

int arr[18] = {1, 5, 28, 4, 3, 2, 10, 20, 18, 25, 21, 29, 34, 35, 14, 100, 27, 19};
int p[] = {20, 30};
sort_r(arr, 18, sizeof(int), sort_r_cmp, p);
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-10T21:25:11+00:00Added an answer on June 10, 2026 at 9:25 pm

    Following the suggestion by @Kirilenko here, I’ve come up with a solution using global variables and a mutex to pass parameters to a sort comparator function. This approach is thread-safe, can do everything achieved with nested functions and should be portable between compilers.

    This example sorts a list of integers, but inverts the sort for a given region.

    // define lock for sort parameters
    pthread_mutex_t lock;
    
    // Parameters used in sort function - invert region (inclusive)
    int invert_start, invert_end;
    
    // Comparison that uses global variables (invert_start, invert_end) as parameters
    int cmp_func(const void *a, const void *b)
    {
      const int aa = *(const int*)a;
      const int bb = *(const int*)b;
    
      if(aa < invert_start || aa > invert_end ||
         bb < invert_start || bb > invert_end)
      {
        return aa - bb;
      }
      else
      {
        return bb - aa;
      }
    }
    
    void sort_things(int* arr, int arr_len, int inv_start, int inv_end)
    {
      // Mutex lock
      pthread_mutex_lock(&lock);
    
      // Set params
      invert_start = inv_start;
      invert_end = inv_end;
    
      // do sort
      qsort(arr, arr_len, sizeof(*arr), &cmp_func);
    
      // Mutex free
      pthread_mutex_unlock(&lock);
    }
    

    Example results:

    input: 1 5 28 4 3 2 10 20 18 25 21 29 34 35 14 100 27 19
    invert_start = 20, invert_end = 30
    output: 1 2 3 4 5 10 14 18 19 29 28 27 25 21 20 34 35 100
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Is it possible to write an interactive defun with code r that has an
I want to write some portable (as possible) C code to look up DNS
Is it possible to write GLSL ES fragment shaders under iOS that generate multiple
Is it possible to write a program that will change the phone numbers a
Possible Duplicate: Is it possible to write to a file (on a disk) using
Please understand, that I am new to microsoft shop development.... I am using silverlight
Possible Duplicate: Write a recursive function that reverses the input Recently, I've been reading
Possible Duplicate: Can I write native iPhone apps using Python I just googled whether
i was wondering if it was possible to write my own firmware that will
Possible Duplicate: Write a function that returns the longest palindrome in a given string

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.