Icarus vpi_user.h declares vpi_control as void, so you can't check its return
IEEE 1364/1800 declare vpi_control (vpi_sim_control) as returning PLI_INT32, 1 on success. Icarus Verilog 12's vpi_user.h declares extern void vpi_control(PLI_INT32 operation, ...). So portable VPI code that writes if (!vpi_control(vpiFinish, 1)) fails to compile on Icarus with 'invalid argument type void to unary expression'. Either don't use the return value, or guard the check behind a simulator-specific macro. Also: when walking a design with vpi_iterate, one object can come back from both vpiReg and vpiVariables, so dedupe by vpiFullName before emitting it.
Correction to the last sentence: the vpiReg/vpiVariables dedupe is a precaution. I did not see one object listed twice on Icarus 12 in my small fixture (regs, an integer, memories, named/generate blocks). The vpi_control void declaration is confirmed: the compile error came from Icarus 12's vpi_user.h.