4

Here is the code as below:

  std::stringstream os;

  os << std::hex; // MISRA warning on this line
  os << std::setw(2);
  os << std::setfill('0');

Warning: "Required Rule 8-4-4, function identifier used without '&' or parenthisized parameter list"

I am not able to resolve this, please suggest a solution.

suhel
  • 321
  • 3
  • 12

7 Answers7

6

Do what the warning says: take the address of the function:

os << &std::hex;
Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
5

How about just using & like suggested ?

#include <iomanip>
#include <iostream>
#include <sstream>

int main() {
    std::stringstream os;

    os << &std::hex; // Works with &
    os << std::setw(2);
    os << std::setfill('0');
    os << 13;

    std::cout << os.str() << "\n";
    return 0;
}

Yes, it works too.


What is the difference ?

  • std::hex is a reference to function
  • &std::hex is a pointer to function

Since references to function have an implicit conversion to pointers to function, you can pass either to an ostream and it will work as expected. Apparently, though, MISRA requires you to be explicit on whether you meant I want the function or I want to invoke the function.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
3

You can do

std::hex(std::cout);

which is equivalent to

std::cout << std::hex;

Which will get rid of the warning. Alternatively, use

std::cout << &std::hex;

but this looks really ugly, although it is correct.

Bottom line is, MISRA is "wrong"/awkward/unexpected here. std::hex can be used as you did without any issues.

rubenvb
  • 74,642
  • 33
  • 187
  • 332
  • I would not say wrong without knowing the *reason*. MISRA is not *just* about preventing undefined/unspecified/implementation-defined behavior. It also issues "style" guidelines, and that might well be one of them... or the OP might have triggered a MISRA-C guideline by inadvertence. – Matthieu M. Jan 30 '14 at 08:43
  • 2
    @MatthieuM. Well, good rules generally have even better exceptions. And I'd say using stream manipulators without taking their address is one - it's normal. Seeing the `&` would actually have me go "wtf?". Of course, some advocates of MISRA say its purpose actually is to make you go "wtf" and thus double-check that the code is correct. – Angew is no longer proud of SO Jan 30 '14 at 08:45
  • @MatthieuM. True enough. But still awkward. Modified my answer a bit. – rubenvb Jan 30 '14 at 08:55
  • 3
    MISRA just doesn't get streams. It also trips over `while(std::cin>>foo)` - implicit conversion. – MSalters Jan 30 '14 at 09:43
2

Maybe this is of-topic, but be ware of using std::stringstream and streams in general. It has a state and by default it doesn't throw. So, in case of insufficient memory, it just set an "error" flag instead of throwing std::bas_alloc which could be a source of very tricky errors and crashes.

check http://www.cplusplus.com/reference/ios/ios/exceptions/

smrt28
  • 469
  • 3
  • 20
1

The line

os << std::hex;

ends up calling the overload

basic_ostream<charT,traits>& basic_ostream::operator<<(basic_ostream<charT,traits>& (*pf)(basic_ostream<charT,traits>&))

which is an operator<<() overload that takes a pointer to a function with a basic_ostream<> argument. That's that std::hex is here.

That operator<<() overload just calls the function through the pointer. So you can do any of the following which are equivalent:

os << &std::hex;    // makes the function pointer explicit using the & operator

std::hex(os);       // call the `std::hex` function using a normal function call syntax

// or directly call the function that `std::hex(os)` is specified to do:
os.setf(std::ios_base::hex, std::ios_base::basefield);

It's too bad that MISRA complains about the idiomatic way of setting an output stream to hex formatting.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
0

First of all, the code you've shown looks quite standard to me.

I see some possible explanations and ways to address the warning accordingly:

  1. The stream manipulator std::hex is implemented MISRA-conformant.

    a) Don't use std::hex.

    b) Fix std::hex. Try to look up the implementation of std::hex in your environment.

  2. The code including std::hex is conformant but the warning is erroneous.

    a) Ignore or suppress the warning.

    b) File a bug report with the supplier of your compiler or code validator.

Peter G.
  • 14,786
  • 7
  • 57
  • 75
  • 2
    Of your possibilities, 1a is the best. The MISRA rule is shortsighted and makes the ISO C++ standard `std::hex` non-conformant. You can't fix it and ISO won't fix it. The correct solution would be for MISRA to fix the rule. But to consider 1a the best solution in the mean time is not very realistic. – MSalters Jan 30 '14 at 09:47
0

You really have three options:

  1. Do not use std::hex
  2. do cout<<&std::hex
  3. Raise a deviation request from the MISRA standard

The first option may not be practical, the second is icky.

Luckily, the MISRA standards expect that the rules will not be slavishly followed - from the MISRA C standard (which is the only one i have text to hand for)

Strict adherence to all rules is unlikely and, in practice, deviations associated with individual situations, are admissible.

This doesn't of course mean you can do what you want, instead, the standard expects a deviation request would be submitted - how this is done is a local matter, and your QMS should cover it. In terms of your tool, there may be an option to ignore on a per occurrence basis.

mjs
  • 2,837
  • 4
  • 28
  • 48