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

Matsmath
  • 1,164
  • 2
  • 21
  • 40
  • "The program should consist of a single translation unit only, i.e. it should be compiled along the lines:" Still multiple translation units though. – tkausl Dec 01 '17 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 – 463035818_is_not_an_ai Dec 01 '17 at 10:34

1 Answers1

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);
}
Community
  • 1
  • 1
Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
  • 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. – user7860670 Dec 01 '17 at 10:42
  • I should have a look at this, thank you for your answer! – Matsmath Dec 01 '17 at 10:42