SQLite User Forum

For sqlite3 in C++, how should I handle a NULL value in the callback function
Login

For sqlite3 in C++, how should I handle a NULL value in the callback function

(1) By anonymous on 2022-02-27 17:00:42 [link] [source]

Apologies in advance as this is probably a very simple thing which I just don't understand properly.

For executing pre-made statements, I use the (admittedly basic) callback function:

int callback(void* NotUsed, int argc, char** argv, char** azColName) {

	//Print out the values called (e.g. in a SELECT statement)
	for (int i = 0; i < argc; ++i) {
		std::cout << azColName[i] << " : " << argv[i] << '\n';
	}
	std::cout << '\n';

	//Return success code.
	return 0;
}

This just prints out the results of the executed statement to the console. So if I call sqlite3_exec() with a pointer to that function as the third parameter, it will print results to the console just fine.

However, when this function comes across a NULL value for argv[i], my program throws an access violation error corresponding to line 409 of the xstring header (code is return __builtin_strlen(_First);).

Evidently my callback function is lacking when it comes to handling NULL values - what is the right way to handle them? Or even just to check if a particular value coming in is NULL so I can treat it differently?

(2.1) By Stephan Beal (stephan) on 2022-02-27 17:11:56 edited from 2.0 in reply to 1 [source]

Evidently my callback function is lacking when it comes to handling NULL values - what is the right way to handle them? Or even just to check if a particular value coming in is NULL so I can treat it differently?

Untested, but something like this should work:

std::cout << azColName[i] << " : " << std::string(argv[i] ? argv[i] : "NULL") << '\n';

(Replace "NULL" with a string of your choice, even an empty one.)

The problem (IIRC, though it's been a while since i've used the STL) is that the << operator is trying to coerce the (char const *) argument to a std::string and that constructor does not like NULL values.

(3) By anonymous on 2022-02-27 17:19:11 in reply to 2.1 [link] [source]

That seems to have done it, thanks.

And thanks for the explanation. That does indeed make a lot of sense. Much appreciated.

(4) By ddevienne on 2022-02-28 09:27:39 in reply to 2.1 [link] [source]

The problem [...] is that the << operator is trying to coerce the (char const *) argument to a std::string

There are op<< operators for const char*, so I don't think std::string has anything to do here. e.g.:

template< class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os,  
                                        const char* s );

But the doc for those operators explicitly says:

The behavior is undefined if s is a null pointer.

So

std::cout << azColName[i] << " : " << (argv[i]? argv[i]: "NULL") << '\n';

Should work fine, and avoid unnecessary copies.