1

I want to build a library (i.e., a collection of functions) acting on vectors/matrices of fixed size. I want to specify this fixed size in the main file, without touching the library. I could do this with using #define, but I view this approach as a hack, rather than the `right' way. What other approaches do I have to achieve this goal? The idea is to write a library once, and then never to touch, or even look at it again.

Here is the following toy example, program.cpp

//program.cpp -- Definition of my_external_constant here
const unsigned int array_size = 10;
#define my_external_constant array_size // I am looking for alternatives.
#include "helper.h"

int main(int argc, char* argv[]) {

    test_function1();

    unsigned int X[array_size];
    X[0]=500;X[1]=0;X[2]=9;X[3]=111;X[4]=0;
    print_vector(X,3);

    return 0;
}

Then helper.h

//helper.h
#ifndef HELPER_H
#define HELPER_H

#include<iostream>

#ifndef my_external_constant    // I want to avoid this...
#define my_external_constant 1  //...and this...
#endif                          //...and this.

void test_function1(void);

//The library uses helper_max_size everywhere, and its value is inherited from outside.
const unsigned int helper_max_size = my_external_constant;
void print_vector(unsigned int[helper_max_size], const unsigned int);

#endif /* HELPER_H */

And the implementation helper.cpp

//helper.cpp
#include "helper.h"

void test_function1(void) {
    std::cout << "Hello world!\n";
    return;
}

void print_vector(unsigned int my_vector[helper_max_size], const unsigned int my_size) {

    for (unsigned int i=0;i<my_size;++i) {
        std::cout << my_vector[i] << " ";
    }
    std::cout << "\n";

    return;
}

The program should consist of a single translation unit only, i.e. it should be compiled along the lines:

g++ -o program program.cpp helper.h helper.cpp

Related:

How do I use extern to share variables between source files?

Declare array size in header file without #define's

2
  • "The program should consist of a single translation unit only, i.e. it should be compiled along the lines:" Still multiple translation units though. Commented Dec 1, 2017 at 10:33
  • 2
    you could start using C++ ;) ... eg make your matrix types templates (parametrized on the size). If you have fixed sized arrays you should use std::array anyhow Commented Dec 1, 2017 at 10:34

1 Answer 1

4

I want to specify this fixed size in the main file, without touching the library.

The idea is to write a library once, and then never to touch, or even look at it again.

Parametrize all utilities and functions in your library over the size of the array. Example:

// helper.h
template <std::size_t N>
void print_vector(unsigned int(&array)[N], const unsigned int) { /* ... */ }

// program.cpp 
#include <cstddef>
#include "helper.h"

constexpr std::size_t array_size = 10;

int main(int argc, char* argv[]) 
{
    test_function1();

    unsigned int X[array_size];
    X[0]=500;X[1]=0;X[2]=9;X[3]=111;X[4]=0;
    print_vector(X, 3);
}

In Modern C++, you should prefer std::array over C-style arrays. You might also want to use std::vector if you need a resizable array. E.g.:

// helper.h
template <std::size_t N>
void print_vector(const std::array<unsigned int, N>& array, const unsigned int) 
{ 
    /* ... */ 
}

// program.cpp 
#include <cstddef>
#include "helper.h"

constexpr std::size_t array_size = 10;

int main(int argc, char* argv[]) 
{
    test_function1();

    std::array<unsigned int, array_size> X;
    X[0]=500;X[1]=0;X[2]=9;X[3]=111;X[4]=0;
    print_vector(X, 3);
}
Sign up to request clarification or add additional context in comments.

2 Comments

I would like to mention the danger of straightforward replacement of raw arrays passed as function parameter with std::array: now entire array will be passed by value (copied) while original code passes only a raw pointer (probably unintentionally because it looks like array). The better idea would be to pass it by const reference.
I should have a look at this, thank you for your answer!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.