Skip to content

dput(..., file = stderr())

3 messages · Benjamin Tyner, Richard M. Heiberger, Ivan Krylov

#
Curious to know if this warning is expected behavior, and if so, what is 
the recommended way instead:

     > dput(letters, file = stderr())
    c("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
    "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y",
    "z")
    Warning message:
    In dput(letters, file = stderr()) : wrote too few characters

(I ask because it doesn't happen when using file = stdout())
#
I see the same thing in a fresh R session
c("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", 
"m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", 
"z")
Warning message:
In dput(letters, file = stderr()) : wrote too few characters
c("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", 
"m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", 
"z")
_                                          
platform       aarch64-apple-darwin20                     
arch           aarch64                                    
os             darwin20                                   
system         aarch64, darwin20                          
status         Patched                                    
major          4                                          
minor          3.2                                        
year           2024                                       
month          01                                         
day            23                                         
svn rev        85822                                      
language       R                                          
version.string R version 4.3.2 Patched (2024-01-23 r85822)
nickname       Eye Holes
#
? Fri, 1 Mar 2024 10:54:08 -0500
Benjamin Tyner <btyner at gmail.com> ?????:
Sounds like a bug.

This is where the warning is produced:

    int res = Rconn_printf(con, "%s\n", CHAR(STRING_ELT(tval, i)));
    if(!havewarned &&
       res < strlen(CHAR(STRING_ELT(tval, i))) + 1) {
	warning(_("wrote too few characters"));
	havewarned = TRUE;
    }

At this point, `res` is 0, and CHAR(STRING_ELT(tval, i)) is what you'd
expect:

(gdb) x /s (void*)(STRING_ELT(tval, i))+48
0x5555561bf0a8: "c(\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\",
\"h\", \"i\", \"j\", \"k\", \"l\", "

`res` is 0 because that's what (con->vfprintf)(...) returns:

2813    static int stderr_vfprintf(Rconnection con, const char *format, va_list ap)
2814    {
2815        REvprintf(format, ap);
2816        return 0;
2817    }

Why doesn't it warn for stdout()? Doesn't stdout_vfprintf(...) behave
the same? That's because stdout() (connection #1) is special for dput(),
and instead of going through the connection system, it goes straight for
Rprintf():

426         else { // ifile == 1 : "Stdout"
427             for (int i = 0; i < LENGTH(tval); i++)
428                 Rprintf("%s\n", CHAR(STRING_ELT(tval, i)));
429         }

Not sure what the right fix is. There may be code depending on
(con->vfprintf)(...) returning 0.