Skip to content
Snippets Groups Projects
Commit 1a19f1c1 authored by Jö Fahlke's avatar Jö Fahlke
Browse files

[release][matrixmarket][ODR] Give the name MatrixMarketImpl to the anonymous

namespace.

This namespace was probably meant to mark implementation details.  However it
led to violations of the ODR (one definition rule), and to warnings about
defined-but-unused functions (see below).

To illustrate the problem consider the function template
Dune::readMatrixMarket:

  template<typename T, typename A, int brows, int bcols>
  void readMatrixMarket(Dune::BCRSMatrix<Dune::FieldMatrix<T,brows,bcols>,A>& matrix,
                        std::istream& istr)
  {
    // ...
    readSparseEntries(matrix, istr, entries, header, NumericWrapper<T>());
  }

The ODR states (§3.2/5):

  There can be more than one definition of a [...] non-static function
  template (14.5.6) [...] in a program provided that each definition appears
  in a different translation unit, and provided the definitions satisfy the
  following requirements.  Given such an entity named D defined in more than
  one translation unit, then

  - each definition of D shall consist of the same sequence of tokens; and

  - in each definition of D, corresponding names, looked up according to 3.4,
    shall refer to an entity defined within the definition of D, or shall
    refer to the same entity, after overload resolution (13.3) and after
    matching of partial template specialization (14.8.3), except that a name
    can refer to a const object with internal or no linkage if the object has
    the same literal type in all definitions of D, and the object is
    initialized with a constant expression (5.19), and the value (but not the
    address) of the object is used, and the object has the same value in all
    definitions of D; and

  [...]

This is violated by e.g. both readSparseEntries, which is defined in the
anonymous namespace.  Since it is not defined within readMatrixMarket, it must
refer to the same entity in all translation units.  However, its name is
effectively Dune::<unique>::readSparseEntries, where <unique> is unique to
each translation unit, and thus it effectively refers to a different entity in
each translation unit, and the program is ill-formed as soon as move than one
translation unit does #include <dune/istl/matrixmarket.hh>.

The warnings by g++-4.9 looked like this:
======================================================================
g++ -std=c++11 -DHAVE_CONFIG_H -I. -I../../..  -pthread -I/home/joe/Projekte/pdelab-2.4/dune-common -I/home/joe/Projekte/pdelab-2.4/dune-common -I../../.. -I/usr/lib/openmpi/include -I/usr/lib/openmpi/include/openmpi -pthread -DMPIPP_H -DENABLE_MPI=1   -g -O3 -Wall -MT matrixmarkettest-matrixmarkettest.o -MD -MP -MF .deps/matrixmarkettest-matrixmarkettest.Tpo -c -o matrixmarkettest-matrixmarkettest.o `test -f 'matrixmarkettest.cc' || echo './'`matrixmarkettest.cc
[...]
In file included from matrixmarkettest.cc:11:0:
../../../dune/istl/matrixmarket.hh:501:10: warning: ‘void Dune::{anonymous}::readNextLine(std::istream&, std::ostringstream&, Dune::{anonymous}::LineType&)’ defined but not used [-Wunused-function]
     void readNextLine(std::istream& file, std::ostringstream&, LineType& type)
          ^
In file included from matrixmarkettest.cc:11:0:
../../../dune/istl/matrixmarket.hh:601:19: warning: ‘std::istream& Dune::{anonymous}::operator>>(std::istream&, Dune::{anonymous}::NumericWrapper<Dune::{anonymous}::PatternDummy>&)’ defined but not used [-Wunused-function]
     std::istream& operator>>(std::istream& is, NumericWrapper<PatternDummy>& num)
                   ^
======================================================================
parent c2a41b1c
No related branches found
No related tags found
No related merge requests found
......@@ -44,7 +44,7 @@ namespace Dune
* @brief Provides classes for reading and writing MatrixMarket Files with
* an extension for parallel matrices.
*/
namespace
namespace MatrixMarketImpl
{
/**
* @brief Helper metaprogram to get
......@@ -695,15 +695,18 @@ namespace Dune
Setter(rows, matrix);
}
} // end anonymous namespace
} // end namespace MatrixMarketImpl
class MatrixMarketFormatError : public Dune::Exception
{};
void mm_read_header(std::size_t& rows, std::size_t& cols, MMHeader& header, std::istream& istr,
void mm_read_header(std::size_t& rows, std::size_t& cols,
MatrixMarketImpl::MMHeader& header, std::istream& istr,
bool isVector)
{
using namespace MatrixMarketImpl;
if(!readMatrixMarketBanner(istr, header)) {
std::cerr << "First line was not a correct Matrix Market banner. Using default:\n"
<< "%%MatrixMarket matrix coordinate real general"<<std::endl;
......@@ -749,6 +752,8 @@ namespace Dune
void readMatrixMarket(Dune::BlockVector<Dune::FieldVector<T,entries>,A>& vector,
std::istream& istr)
{
using namespace MatrixMarketImpl;
MMHeader header;
std::size_t rows, cols;
mm_read_header(rows,cols,header,istr, true);
......@@ -780,6 +785,8 @@ namespace Dune
void readMatrixMarket(Dune::BCRSMatrix<Dune::FieldMatrix<T,brows,bcols>,A>& matrix,
std::istream& istr)
{
using namespace MatrixMarketImpl;
MMHeader header;
if(!readMatrixMarketBanner(istr, header)) {
std::cerr << "First line was not a correct Matrix Market banner. Using default:\n"
......@@ -863,6 +870,8 @@ namespace Dune
void mm_print_vector_entry(const V& vector, std::ostream& ostr,
const integral_constant<int,0>&)
{
using namespace MatrixMarketImpl;
// Is the entry a supported numeric type?
const int isnumeric = mm_numeric_type<typename V::block_type>::is_numeric;
typedef typename V::const_iterator VIter;
......@@ -884,6 +893,8 @@ namespace Dune
void writeMatrixMarket(const V& vector, std::ostream& ostr,
const integral_constant<int,0>&)
{
using namespace MatrixMarketImpl;
ostr<<countEntries(vector)<<" "<<1<<std::endl;
const int isnumeric = mm_numeric_type<typename V::block_type>::is_numeric;
mm_print_vector_entry(vector,ostr, integral_constant<int,isnumeric>());
......@@ -916,6 +927,8 @@ namespace Dune
void writeMatrixMarket(const M& matrix,
std::ostream& ostr)
{
using namespace MatrixMarketImpl;
// Write header information
mm_header_printer<M>::print(ostr);
mm_block_structure_header<M>::print(ostr,matrix);
......@@ -1020,6 +1033,8 @@ namespace Dune
OwnerOverlapCopyCommunication<G,L>& comm,
bool readIndices=true)
{
using namespace MatrixMarketImpl;
typedef typename OwnerOverlapCopyCommunication<G,L>::ParallelIndexSet::LocalIndex LocalIndex;
typedef typename LocalIndex::Attribute Attribute;
// Get our rank
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment