help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Oct-file error message construction and octave_value conversions


From: Kai Torben Ohlhus
Subject: Re: Oct-file error message construction and octave_value conversions
Date: Wed, 30 Jan 2019 11:41:18 +0100



On Wed, Jan 30, 2019 at 1:40 AM Andrew Janke <address@hidden> wrote:
Hi, folks,

Thanks for bearing with me and all my questions on oct-files in IRC.

I'm trying to construct detailed error messages for some of my oct
functions that incorporate size, type, and value info about their
inputs, but having a hard time doing so. Here's what I'm trying:

#include <cmath> #include <iostream> #include <octave/oct.h> DEFUN_DLD (s01_02_error_msg_string_construction, args, nargout,
            "Error message construction using argument type")
{
   octave_value x = args(0);

   std::string x_type_name = x.type_name ();
   std::string msg =std::string ("Type of arg 1 is: ")+ x_type_name;
   error (msg.c_str ());

   builtin_type_t x_type = x.builtin_type ();
   std::string msg2 =std::string ("Builtin type id of arg 1 is: ")+ x_type;
   error (msg2.c_str ());

   octave_idx_type n_elems = x.numel ();
   std::string msg3 =std::string ("Numel in arg 1: ")+ n_elems;
   error (msg3.c_str ());
}


The first "msg = ..." statement works. But each of those
other "msgX = ..." lines is giving me a compiler error. It's complaining
that "no viable conversion from 'octave_value' to 'std::string'". Which is weird,
because builtin_type_t and octave_idx_type are not octave_values, are they?
builtin_type_t is an enum, and octave_idx_type is a typedef to an integer type.
Why does the compiler think an octave_value is involved here?

(BTW, yes, I know I should be using type_name() and not builtin_type(); I'm just
including it here to help track down the conversion issue I'm not understanding.)

I'd like to stick with constructing std::string messages instead of using the printf style
controls that error accepts (like 'error ("Numel in arg 1: %ld", (long) octave_idx_type)')
because I want to use these with generic templated functions that will use the template
types in the error message construction; "std::string + x" is polymorphic, but printf
placeholders are not.

Cheers,
Andrew





Hi Andrew,

Somehow I got interested in your problem and hope to present a satisfactory answer found by try&error and [1,2] to both of us.
The problem is best explained with the following program:

====== CODE START ========
// Compile with: g++ -std=c++11 -I/path/to/octave -pedantic -Wall -Wextra -o test.exe test.cc

#include <iostream>
// #include <octave/oct.h>

int main () {
  int x_type_name = 12;
  // Without <octave/oct.h>
  // error: no match for ‘operator+’ (operand types are
  //   ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ and ‘int’)

  // With <octave/oct.h>
  // error: conversion from ‘octave_value’ to non-scalar type
  //   ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ requested
  std::string msg = std::string ("Type of arg 1 is: ") + x_type_name;
  return 0;
====== CODE END ========

As you can see, the root problem is that there is nothing like

   std::string::operator+(int);

Now g++ is desperate, but not beaten yet: It tries to find a matching operator even harder.
My guess is when oct.h is included you get a bunch of new operators:

a) there is an operator  octave_value::operator+(octave_value)
b) there are constructors octave_value(std::string) and octave_value(int)
c) g++ tries to make use of it, as there is nothing better suited
==> PROBLEM: there is nothing like  std::string(octave_value)  for implicit back conversion. And that is the error message in this case.

Bottomline, this is not Octaves fault try to use "std::to_string" [3] to help g++ with its operator finding, i.e.

   std::string msg3 =std::string ("Numel in arg 1: ") + std::to_string (n_elems);

and you can go on.

Best,
Kai


reply via email to

[Prev in Thread] Current Thread [Next in Thread]