0

Here's the function prototype declaration defined in utils.hpp (NON OOP, so not in any class)

static void create_xy_table(const k4a_calibration_t *calibration, k4a_image_t xy_table);

static void generate_point_cloud(const k4a_image_t depth_image,
                                 const k4a_image_t xy_table,
                                 k4a_image_t point_cloud,
                                 int *point_count);

static void write_point_cloud(const char *file_name, const k4a_image_t point_cloud, int point_count);

And I have their definitions in utils.cpp which includes utils.hpp.

When I call use any of the function at main function in main.cpp, I get the following error:

/tmp/ccFcMfYB.o: In function `main':
main.cpp:(.text+0x208): undefined reference to 
`create_xy_table(_k4a_calibration_t const*, _k4a_image_t*)

Compilation command:

g++ -o build/testtest src/main.cpp src/utils.cpp -I./include -lk4a

Defining all functions as not static and compiling works perfectly!! I can't wrap my head around this.

  • What exactly is happening?
  • What should one do to properly include / link if one needs to define and link static functions?

My System Config: gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)

EDIT: Here's my function definition in utils.cpp:

static void create_xy_table(const k4a_calibration_t *calibration, k4a_image_t xy_table)
{
    k4a_float2_t *table_data = (k4a_float2_t *)(void *)k4a_image_get_buffer(xy_table);

    int width = calibration->depth_camera_calibration.resolution_width;
    int height = calibration->depth_camera_calibration.resolution_height;

    k4a_float2_t p;
    k4a_float3_t ray;
    int valid;

    for (int y = 0, idx = 0; y < height; y++)
    {
        p.xy.y = (float)y;
        for (int x = 0; x < width; x++, idx++)
        {
            p.xy.x = (float)x;

            k4a_calibration_2d_to_3d(
                calibration, &p, 1.f, K4A_CALIBRATION_TYPE_DEPTH, K4A_CALIBRATION_TYPE_DEPTH, &ray, &valid);

            if (valid)
            {
                table_data[idx].xy.x = ray.xyz.x;
                table_data[idx].xy.y = ray.xyz.y;
            }
            else
            {
                table_data[idx].xy.x = nanf("");
                table_data[idx].xy.y = nanf("");
            }
        }
    }
}

EDIT2: Here is how I have done things in main.cpp.

k4a_calibration_t calibration;
k4a_image_t xy_table = NULL;
/*
Calibration initialization codes here
*/
create_xy_table(&calibration, xy_table);
scimad.om
  • 3
  • 3
  • 1
    compiler error says it all. Function call have`_k4a_image_t*` but declaration have `_k4a_image_t` – The Philomath Nov 21 '19 at 05:58
  • 1
    @ThePhilomath: Does it actually? Please refer to the edit section of my question, I have not used it like you have said in the comment. Furthermore, why would declaring those non static solve the problem? – scimad.om Nov 21 '19 at 06:07
  • @Evg: On why do I want them to be static, I don't really need those to be static. I already have made those non static and used for my application. But I want to understand what is going on. Can you kindly elaborate what you mean by "private to this compilation unit"? What do you mean by "compilation unit" here? – scimad.om Nov 21 '19 at 06:11
  • 1
    As to @ThePhilomath comment, show your `main.cpp`. It's not clear why it refers to `create_xy_table(_k4a_calibration_t const*, _k4a_image_t*)` (note the asterisk after `_k4a_image_t`). – Evg Nov 21 '19 at 06:21
  • @Evg, please refer to **EDIT2** section for main.cpp – scimad.om Nov 21 '19 at 07:06
  • It seems that `k4a_image_t = _k4a_image_t*`. I didn't notice the leading `_`. – Evg Nov 21 '19 at 07:08
  • @Evg .. Oh I missed that – The Philomath Nov 21 '19 at 07:25
  • Why have you added the `static` keyword in the first place? – n. m. could be an AI Nov 21 '19 at 07:28
  • It was in the SDK's example (Kinect for Azure) [here](https://github.com/microsoft/Azure-Kinect-Sensor-SDK/blob/develop/examples/fastpointcloud/main.cpp) which I tried to break down for my use. And thank you everyone for the light. – scimad.om Nov 21 '19 at 07:34

2 Answers2

6

When you put implementations into a separate compilation unit (a .cpp file) you ask a linker to find these implementations later when objects files are linked together. When you declare a function as static, you say that this function should not be visible in other compilation units (this is knows as internal linkage).

Now, you include a header with static functions. utils.cpp will get its own copies, which will be invisible for all other compilation units. main.cpp will see only declarations, but not implementations, so no code will be generated. That's why you get a linking error - the code is in utils.cpp, but it is not accessible to anyone.

If you for some reason want to include static functions, you should provide their implementation in the header file. Then each compilation unit will get its own private copy of them.

Evg
  • 25,259
  • 5
  • 41
  • 83
0

static modifier in c/c++ limits the function definition to one compilation unit (utils.cpp). These functions are then not visible/accessible from other compilation units e.g. main.cpp in your case.

Atif Alam
  • 36
  • 2