All;
My setup: Linux Debian
12 (bookworm) with gcc/g++ 12, EPICS 7.0.7.
We recently starting using EPICS 7 for our IOCs, and it's been going (mostly) smoothly so far. But yesterday I ran into an issue where an IOC shell command in one of my c++ modules no longer properly pipes to an output file. It creates a 0-byte file but
the output just displays in the shell, it's not written to the file.
I went looking for why that was. I lazily use "printf"s in my code, include <epicsStdioRedirect.h> at the top, and the magic has always just happened. But in EPICS 7 it turns out that the macro redefinition of "printf" is getting stepped on by other include
files. In my case, by including <epicsTime.h> after the include of <epicsStdioRedirect.h>.
epicsTime.h includes <stdexcept>, which touches off a string of other includes until it finally includes <cstdio>, which does an #undef printf thus removing the printf redefinition made by epicsStdioRedirect.h (well, epicsStdio.h). I found there are other
header files in EPICS base 7 that include <stdexcept>, epicsTime.h was just the one that got me.
This isn't particular to gcc 12, btw, I went looking on an older
IOC with gcc 10 and it has the same string of includes from stdexcept. But it's using EPICS 3.15.9 and it's epicsTime.h doesn't include <stdexcept>, so the magic happened okay.
I have a test.cpp and a Makefile that recreate the problem, if
anyone wants to play around with it. For now I'm just including <epicsTime.h> BEFORE <epicsStdioRedirect.h> and the magic works again. I also tried patching epicsTime.h with a kludge to re-include <epicsStdio.h> after <stdexcept> and that worked:
// KLUDGE
#ifdef epicsStdioh
#ifndef printf
#undef epicsStdioh
#include <epicsStdio.h>
#endif
#endif
But as advertised, that's a kludge. What I should *probably* do is replace all my printf()s with epicsStdoutPrintf()s, but that's a lot of code revision, so for now I'm going with my work-around on changing order of includes.
Thanks,
JP