Ошибка сегментации с armadillo + make при изменении флага компилятора g ++ на -std = c ++ 11 - PullRequest
0 голосов
/ 17 мая 2018

Макет проекта

├── CMakeLists.txt
├── README.md
├── cppml.pc.in
├── examples
│   ├── AccuracyScoreEx.cpp
│   └── CMakeLists.txt
├── include
│   └── cppml
│       ├── Prerequisites.h
│       └── metrics
│           └── AccuracyScore.h
└── src
    ├── CMakeLists.txt
    └── metrics
        └── AccuracyScore.cpp

Содержимое корня CMakeLists.txt

cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
project(cppml VERSION 1.0.1 LANGUAGES CXX)
include(GNUInstallDirs)

find_package(Armadillo REQUIRED)

configure_file(cppml.pc.in cppml.pc @ONLY)

add_subdirectory(src)
add_subdirectory(examples)
#add_subdirectory(tests)

Содержимое src/CMakeLists.txt

# set source files
set (sources
  metrics/AccuracyScore.cpp
)

# define library targets
add_library(cppml SHARED
  ${sources}
)

# target properties
set_target_properties(cppml PROPERTIES
 VERSION ${PROJECT_VERSION}
 SOVERSION 1
 CXX_VISIBILITY_PRESET hidden
)

# define headers for this lib. PUBLIC headers are used for compiling
# the library, and will be added to user's build path.
target_include_directories(cppml PUBLIC
  $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
  $<INSTALL_INTERFACE:include>
  PRIVATE ${PROJECT_SOURCE_DIR}/src
)

# Link with externel libs
target_link_libraries(cppml ${ARMADILLO_LIBRARIES})

# target_compile_features(cppml
#   PUBLIC
#     cxx_std_11 #XXX: PROBLEM HERE!
# )

# Install
install(TARGETS cppml
  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ 
  DESTINATION     ${CMAKE_INSTALL_INCLUDEDIR}
)

install(FILES ${CMAKE_BINARY_DIR}/cppml.pc
  DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig
)

Проблема в том, что когда я собираю проект с вышеуказанной настройкой, то это дает правильный результат:

g++  -o AccuracyScoreEx AccuracyScoreEx.cpp -lcppml

, но не это:

g++ -std=c++11 -o AccuracyScoreEx AccuracyScoreEx.cpp -lcppml
./AccuracyScoreEx
Segmentation fault: 11

Вот исходные коды:

Prerequisites.h:

#ifndef INCLUDE_CPPML_PREREQUISITES_H_
#define INCLUDE_CPPML_PREREQUISITES_H_

//  armadillo
#include <armadillo>

#endif  // INCLUDE_CPPML_PREREQUISITES_H_

AccuracyScore.h:

#ifndef INCLUDE_CPPML_METRICS_ACCURACYSCORE_H_
#define INCLUDE_CPPML_METRICS_ACCURACYSCORE_H_

#include "cppml/Prerequisites.h"

namespace cppml {
namespace metrics {

extern "C" double accuracy_score(const arma::ivec &y_true,
                    const arma::ivec &y_pred,
                    const bool normalize = true,
                    const arma::vec &sample_weight = arma::vec());

}  // namespace metrics
}  // namespace cppml

#endif  // INCLUDE_CPPML_METRICS_ACCURACYSCORE_H_

AccuracyScore.cpp:

#include "cppml/metrics/AccuracyScore.h"

#define EXPORT __attribute__((visibility("default")))

namespace cppml {
namespace metrics {

EXPORT
double accuracy_score(const arma::ivec &y_true,
                  const arma::ivec &y_pred,
                  const bool normalize,
                  const arma::vec &sample_weight) {

  arma::uvec score = (y_true == y_pred);
  arma::vec dscore = arma::conv_to<arma::vec>::from(score);

  if (normalize) {
    return (sample_weight.n_elem > 0) ? 
            arma::mean(dscore % sample_weight) : 
            arma::mean(dscore);
  } else if (sample_weight.n_elem > 0) {
    return arma::dot(dscore, sample_weight);
  } else {
    return arma::sum(dscore);
  }
}

}  // namespace metrics
}  // namespace cppml

После небольшого взлома с gdb оказывается, что этот парень y_true == y_pred (поэлементное сравнение, выдает либо 0, либо 1) вызывает проблему segmentation fault.Но почему это произошло только при включенном '-std = c ++ 11'?

Редактировать : Добавлен пример программы AccuracyScoreEx.cpp:

#include <iostream>
#include <cppml/metrics/AccuracyScore.h>

int main(int argc, char **argv) {
  arma::ivec y_true;
  y_true << -1 << 1 << 1 << 1;
  arma::ivec y_pred;
  y_pred << 1 << 1 << -1 << 1;
  std::cout << "Accuracy score: ";
  std::out << cppml::metrics::accuracy_score(y_true, y_pred);
  return 0;
}

Любая помощь будет принята с благодарностью!

...