Re: [Vala] printf question



Hi,
one could consider this as cheating and it (might be |is) not as performant as the format string but you can 
just use the glib magic and call .to_string() for nearly any type you want. Here is a simple example:

public static int main(string[] args) {
        int64 test = 0;
        print("%s\n", test.to_string());
        return 0;
}

Which compiles to this:

#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>

#define _g_free0(var) (var = (g_free (var), NULL))



gint _vala_main (gchar** args,
                 int args_length1);


gint
_vala_main (gchar** args,
            int args_length1)
{
        gint result = 0;
        gint64 test = 0LL;
        gchar* _tmp0_;
        gchar* _tmp1_;
        test = (gint64) 0;
        _tmp0_ = g_strdup_printf ("%" G_GINT64_FORMAT, test);
        _tmp1_ = _tmp0_;
        g_print ("%s\n", _tmp1_);
        _g_free0 (_tmp1_);
        result = 0;
        return result;
}


int
main (int argc,
      char ** argv)
{
        return _vala_main (argv, argc);
}


Never gives you headaches to remember the correct format strings. So if you like no headaches and the actual 
print is only for debug you can just use .to_string();

The funny thing is that the "optimized example" of Al Thomas , which uses the format strings  compiles to 
this:


#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>

#define _g_free0(var) (var = (g_free (var), NULL))



void _vala_main (void);


void
_vala_main (void)
{
        gint64 a = 0LL;
        gchar* _tmp0_;
        gchar* _tmp1_;
        gchar* _tmp2_;
        gchar* _tmp3_;
        a = 1234567890123456789LL;
        _tmp0_ = g_strdup_printf ("%li\n", (glong) ((gint32) a));
        _tmp1_ = _tmp0_;
        g_print ("%s", _tmp1_);
        _g_free0 (_tmp1_);
        _tmp2_ = g_strdup_printf ("%lli\n", a);
        _tmp3_ = _tmp2_;
        g_print ("%s", _tmp3_);
        _g_free0 (_tmp3_);
}


int
main (int argc,
      char ** argv)
{
        _vala_main ();
        return 0;
}

Which also calls g_strdup_printf. Therefore without looking at the actual implementation of  g_strdup_printf 
I would not care that much about performance between using format strings vs a simple .to_string().

If you want to make it faster you need to call stdout.printf() direclty e.g.

void main () {
        int64 a = 1234567890123456789LL;
        stdout.printf("%lli\n", a);
}

Which compiles to:

#include <glib.h>
#include <glib-object.h>
#include <stdio.h>




void _vala_main (void);


void
_vala_main (void)
{
        gint64 a = 0LL;
        FILE* _tmp0_;
        a = 1234567890123456789LL;
        _tmp0_ = stdout;
        fprintf (_tmp0_, "%lli\n", a);
}


int
main (int argc,
      char ** argv)
{
        _vala_main ();
        return 0;
}




Best regards,
Bernhard


Al Thomas via vala-list wrote on 09.10.2018 18:57:

 > On Tuesday, 9 October 2018, 16:16:44 BST, wolfgang mauer kabelmail de
 <wolfgang mauer kabelmail de> wrote:  > Is this a Bug?
cellRendererText.text = ("%"+int64.FORMAT).printf((int64)obj); <<----
int64.FORMAT = "li"
this works, but when i try this, witch is the same
cellRendererText.text = ("%li").printf((int64)obj);
i get thiss error 
application.vala:192.45-192.54: error: Argument 1: Cannot convert from `int64'
to `long'

I think it should be %lli. Try:

void main () {
    int64 a = 1234567890123456789LL;
    print ("%li\n".printf ((int32)a));
    print ("%lli\n".printf (a));
}

A 'long' is at least 32 bits, a 'long long' is at least 64 bits. A good summary
is https://en.wikipedia.org/wiki/C_data_types
I think that was the conclusion I came to when I wrote that up in the Genie
docs: https://wiki.gnome.org/Projects/Genie#Numbers

int64.FORMAT in Vala is bound to GLib's G_GINT64_FORMAT. See the Vala binding:
https://gitlab.gnome.org/GNOME/vala/blob/master/vapi/glib-2.0.vapi#L687
The GLib documentation advises 'This is the platform dependent conversion
specifier for scanningand printing values of type gint64'  See
https://developer.gnome.org/glib/2.56/glib-Basic-Types.html#G-GINT64-FORMAT:CAPS
To my mind that is wrong in GLib. Now there may be some platform reason for
doing this, but I suggest you raise an issue with GLib at
https://gitlab.gnome.org/GNOME/vala/issues then we can take it from there. 

Note how the use of just %li in my code example truncates the number. The Vala
compiler is recognising this in your second example and giving an error. If you
cast to int32 it should compile. The Vala compiler has not been set up to
recognise the creation of %li using string concatenation. So it is passed
through to the output C and the C compiler does its thing with a resulting
potential loss of data. Is this a bug in the Vala compiler? May be, but there
may also be a limit to how much checking can be coded in to the compiler. Of
course if someone submitted a patch that made it just work then that would be a
different story :) BTW to read the generated C code use the --ccode switch with
valac.

Hope that helps,

Al
 
_______________________________________________
vala-list mailing list
vala-list gnome org
https://mail.gnome.org/mailman/listinfo/vala-list




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]