Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

memset used with zero length parameter: ignore or watch out?

Tags:

c++

warnings

I'm having trouble finding any information regarding the following warning when linking a dynamic library:

In function `MyClass::myfunc()':
MyClass.cpp:(.text+0x14e4): warning: memset used with constant zero length parameter; this could be due to transposed parameters

Here is an excerpt of myfunc:

void MyClass::myfunc() {
    vector<Variable*>::const_iterator it;

    for (it = m_vars.begin();
         it != m_vars.end();
         ++it) {
        if ((*it)->recordme) {
            MyRecord* r = new MyRecord(*it);
            initMyRecord(*r);
            m_records.push_back(r);
        }
    }
}

So I'm pretty much stuck on were should I be looking for possible causes for this memset. The call to the new operator is my first suspect, but I'm not even sure if it's worth looking for this. I'm not sure either if I should take this warning seriously or let it pass.

Question: what should I do about this warning? And what kind of patterns should I look out for in order to assure that I'm not going to shoot myself in the foot later?

Update: Here is the MyRecord constructor, which is in a header file, so it might or might not be inlined, if I understand correctly.

class MyRecord {
public:
    MyRecord(const Variable* var) :
        buffer(0),
        lastSave(-1 * std::numeric_limits<double>::max()),
        sample(100),
        bufsize(100),
        gv(var),
        rec_function(0)
    {};
    virtual ~Record() {
        if (rec_function)
            delete rec_function;
        rec_function = 0;
    };

private:
    Record(const Record&);
    Record& operator=(const Record& rec);

public: // @todo: remove publicness
    boost::circular_buffer< boost::tuple<double,boost::any> > buffer;
    double lastSave;
    double sample;
    unsigned int bufsize;
    const Variable* gv;
    RecordFunctor* rec_function;
};

The RecordFunctor is a pure-virtual struct:

struct RecordFunctor {
    virtual ~RecordFunctor() {};
    virtual void record(const double) = 0;
};

Additional info? I'm compiling with flags -O2 and g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1

like image 659
YuppieNetworking Avatar asked Jul 09 '12 19:07

YuppieNetworking


People also ask

Is memset faster than fill?

Roughly speaking, the memset function is 15 times faster than std::fill in my test.

What can be used instead of memset in C?

I have used calloc(), instead of combination of malloc and memset as a work around. calloc is the functional equivalent of malloc + memset.

Is STD fill faster?

+1 for std:fill(), this is the C++ way, unless a real need in performance is needed. @StephaneRolland at least in GCC with -O2 std∷fill is faster.


2 Answers

The behavior of the memset() function with a size of 0 is well defined, as long as the pointer argument is valid.

See section 7.21.1 of the C99 standard, or 7.24.1 of the C11 standard:

Where an argument declared as size_t n specifies the length of the array for a function, n can have the value zero on a call to that function.

On the other hand, the warning is a sensible one; a call like memset(s, 0, 0) is not dangerous, but it's not useful (it does nothing), and could easily indicate a programming error.

Greg's answer explains how to avoid it in this case.

like image 84
Keith Thompson Avatar answered Feb 19 '23 16:02

Keith Thompson


You are calling the boost::circular_buffer constructor with a capacity of 0. This probably causes that constructor to call memset() to initialise the storage used by the circular buffer, but you've told it you want a buffer of zero size.

The solution is to give the circular_buffer constructor the actual size you want, not zero (zero doesn't make sense).

like image 32
Greg Hewgill Avatar answered Feb 19 '23 15:02

Greg Hewgill