0

I am trying to have a member array in a class with its length specified by the const static int variable for future needs.

My compiler throws an error with it, and I am not sure this is an error about a uniform initialization or array initialization, or both.

Here is the header file:

#ifndef SOUECE_H
#define SOURCE_H

class Test
{
public:
    Test();
    static const int array_length{2};
    double array[array_length];
};

#endif

This is the source file.

#include "source.h"

Test::Test()
    :array_length{0} //Typo of array{0}
{
}

These are the problem messages.
[enter image description here][1] [1]: https://i.stack.imgur.com/IQ2Mk.png

This is the CMake file.

cmake_minimum_required(VERSION 3.0.0)
project(temp VERSION 0.1.0)

include(CTest)
enable_testing()

add_executable(temp main.cpp)

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

Finally, these are what the compiler is complaining about when I try to build the project.

[main] Building folder: temp 
[build] Starting build
[proc] Executing command: /usr/local/bin/cmake --build /Users/USERNAME/Desktop/temp/build --config Debug --target all -j 14 --
[build] [1/2  50% :: 0.066] Building CXX object CMakeFiles/temp.dir/main.cpp.o
[build] FAILED: CMakeFiles/temp.dir/main.cpp.o 
[build] /usr/bin/clang++   -g -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk -MD -MT CMakeFiles/temp.dir/main.cpp.o -MF CMakeFiles/temp.dir/main.cpp.o.d -o CMakeFiles/temp.dir/main.cpp.o -c ../main.cpp
[build] In file included from ../main.cpp:1:
[build] ../source.h:8:22: error: function definition does not declare parameters
[build]     static const int array_length{2};
[build]                      ^
[build] ../source.h:9:18: error: use of undeclared identifier 'array_length'
[build]     double array[array_length];
[build]                  ^
[build] 2 errors generated.
[build] ninja: build stopped: subcommand failed.
[build] Build finished with exit code 1

I am using macOS 12.0 beta, with VS Code 1.60.2, clang 13.0.0, CMake 3.20.2.

Please let me know if you see any wrong or have any suggestions.

lighthouse
  • 413
  • 2
  • 10
  • The size of a C array must be known at compile-time. Use `static constexpr int array_length{2}` instead. – m88 Sep 27 '21 at 13:02
  • @m88 A `static const int` is also a compile time constant. http://coliru.stacked-crooked.com/a/053c37f04f507ffa – NathanOliver Sep 27 '21 at 13:10

2 Answers2

1

This cannot work:

Test::Test()
    :array_length{0}

You cannot set a const static data member in your constructor. A static value has the same value accross all object instances. But as it is also const no instance is allowed to change the value.

RoQuOTriX
  • 2,871
  • 14
  • 25
0

Since array_length is static const you have to initialize it like this:

source.h

#ifndef SOUECE_H
#define SOURCE_H

class Test
{
public:
    Test();
    static const int array_length = 2;
    //static const int array_length{2}; this will also work just note that we cannot use constructor initializer list to initialize static data members
    double array[array_length];
};

#endif

source.cpp

#include "source.h"

Test::Test()//we cannot use constructor initializer list to initialize array_length
    
{
}

Note that static const int array_length{2}; will also work but the thing is that in the constructor we cannot use constructor initializer list to initialize static data member.

EDIT: If you decide to use static const int array_length{2}; then make sure that you have C++11(or later) enabled in your CMakeLists.txt. For this you can add

set (CMAKE_CXX_STANDARD 11)

to your CMakeLists.txt.

Alternatively, you could instead add

target_compile_features(targetname PUBLIC cxx_std_11)

in your CMakeLists.txt. In your case replace targetname with temp since that is the targetname that you have. Check this out for more how to active C++11 in CMake .

Jason
  • 36,170
  • 5
  • 26
  • 60
  • Oh, You got the issue. Your fix actually did the trick. :) So, `static` variables could not be 'uniform' initialized, right? – lighthouse Sep 27 '21 at 13:02
  • @chanwooahn Even `static const int array_length{2};` would work. The thing is that we can't use constructor initializer list to intialize static data members. – Jason Sep 27 '21 at 13:07
  • It seems not working. Please check out the edit. – lighthouse Sep 27 '21 at 13:17
  • Check this works at this link: https://onlinegdb.com/vs3jOpZld – Jason Sep 27 '21 at 13:19
  • @chanwooahn You can see that this work at 1) https://wandbox.org/permlink/2SCqLD7NssBTjLLo and 2) https://onlinegdb.com/vs3jOpZld – Jason Sep 27 '21 at 13:27
  • I did check your link and see that works, but I don't know why my compiler is still throwing errors. – lighthouse Sep 27 '21 at 13:55
  • [build] ../source.h:8:22: error: function definition does not declare parameters – lighthouse Sep 27 '21 at 13:56
  • [build] static const int array_length{2}; – lighthouse Sep 27 '21 at 13:56
  • [build] ^ [build] ../source.h:9:18: error: use of undeclared identifier 'array_length' – lighthouse Sep 27 '21 at 13:56
  • It's somehow talking about function at the declaration of the member variable. – lighthouse Sep 27 '21 at 13:59
  • Try this: Create 3 files named source.h, source.cpp and main.cpp(as you already have). Next execute the command `g++ main.cpp source.cpp -o program` and see if it works. This should work. – Jason Sep 27 '21 at 14:18
  • @chanwooahn The problem is that you must tell CMake to use C++11(or later). Add the statement `set (CMAKE_CXX_STANDARD 11)` in your CMakeLists.txt. This will fix your problem. – Jason Sep 27 '21 at 14:28
  • @chanwooahn Check out my Edit. It explains how to resolve the error you are getting. You can add `set (CMAKE_CXX_STANDARD 11)` in your CMakeLists.txt file to get rid of the error. Alternatively, you can add `target_compile_features(temp PUBLIC cxx_std_11)` in your CMakeLists.txt file. – Jason Sep 27 '21 at 15:30
  • I did try both of your solutions and the former did not do the trick but the latter do. Maybe I need to dig in more about the difference between them. Do you have any suggestions about where to start from? – lighthouse Sep 27 '21 at 17:32
  • @chanwooahn I have added the link in my answer where you can read more about "how to activate C++11 in CMake" . Can you mark my answer correct if it solved your problem. – Jason Sep 27 '21 at 17:37