I am working in a Linux terminal-command line environment, no IDE. I compile my c++ programs with g++. This one depends on using command line macros to execute different code statements without changing the source code itself. Here is the chunk of code where I have an issue. I have several different arrays that I want to perform a sorting on. Then I have functions somewhere else in the source code that perform that sorting and return the sorted array. I want to use command line macros to tell the preprocessor which array I want to use, and which sorting algorithm to use (which function to call). SORT_ALG
should be replaced with the name of the function, and ARRAY
should be replaced with the name of the array. So after preprocessing, the line should look like this:
int* sorted_array = BubbleSort(array1, array1_size);
Here is the source code:
int array1[] = {24, 13, 9, 64, 7, 23, 34, 47};
int array1_size = sizeof(array1) / sizeof(array1[0]);
// an already sorted array!
int array2[] = {1, 2, 5, 8, 10, 15, 20, 25, 30};
int array2_size = sizeof(array2) / sizeof(array2[0]);
// a reverse sorted array!
int array3[] = {75, 50, 45, 30, 25, 18, 17, 12, 10, 6, 5};
int array3_size = sizeof(array3) / sizeof(array3[0]);
/*
* This code uses command line macros defined by g++
* SORT_ALG should be one of the sorting function names such as:
* BubbleSort
* BubbleSortOptimized
* ARRAY should be the name of one of the arrays, without the brackets:
* array1
* array2
* array3
* Example of compiling the program with g++ using command line macros:
* g++ -D SORT_ALG=BubbleSort -D ARRAY=array1 sorting.cpp
*/
int* sorted_array = SORT_ALG(ARRAY, ARRAY_size);
cout << "The sorted array: ";
PrintArray(sorted_array, ARRAY_size);
cout << endl;
When I try to compile the source code, the preprocessor doesn't recognize to replace ARRAY_size
with the corresponding variable: array1_size
.
$ g++ -D SORT_ALG=BubbleSort -D ARRAY=array1 sorting.cpp
sorting.cpp: In function ‘int main()’:
sorting.cpp:139:39: error: ‘ARRAY_size’ was not declared in this scope
int* sorted_array = SORT_ALG(ARRAY, ARRAY_size);
I think that the preprocessor should recognize the ARRAY
being array1
and then replace ARRAY_size
with array1_size
. I think that it would be good to not have to define another command line macro to specify the size of the array because I would have to count the number of elements, and I'm going to be using this for situations where I don't know the size of the array in advance. So I have the compiler determine the size of the array. Is the underscore the reason why the preprocessor fails its job? It is better to use a different naming convention for the size of the array, to make it be preprocessed correctly? What other kind of approach would you suggest to fix this problem?
From a preprocessor perspective, you can't define a macro FOO
to be BAR
and expect FOO_size
to become BAR_size
because FOO
and FOO_size
are different tokens.
You can, however, create a paste macro to stage this:
#define GLUE(a,b) GLUEI(a,b)
#define GLUEI(a,b) a##b
...
int* sorted_array = SORT_ALG(ARRAY, GLUE(ARRAY,_size));
The macro needs to come in a pair with an indirect macro to allow its arguments to expand. Due to macro expansion rules, ARRAY
in the macro will expand first (given the indirection), which means if you define it to be something else that will apply before the pasting.
But outside the preprocessor perspective, why are you bothering to use the matching pair tokens anyway? If array1_size
is just going to be assigned to sizeof(array1) / sizeof(array1[0])
, you could just change this to SORT_ALG(ARRAY, (sizeof(ARRAY)/sizeof(ARRAY[0])))
.
(Also, what exactly are you doing here? It looks like there could be a much better implementation in C++ if you're doing anything more complex than benchmarking something specific; and I'm puzzled why you're using the command line to switch between algorithms).