Coding: Fleeting Thoughts

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

User avatar
Aaeriele
Posts: 2127
Joined: Tue Feb 23, 2010 3:30 am UTC
Location: San Francisco, CA

Re: Coding: Fleeting Thoughts

Postby Aaeriele » Mon Dec 17, 2012 3:45 pm UTC

Ubik wrote:People who responded to me: Thanks for your feedback and thoughts. I think I'll end up turning once back to the dark side, and start fiddling with C++.


If you want to learn something C-like, but don't want to fiddle with build tools, perhaps Go might be an interesting choice?
Vaniver wrote:Harvard is a hedge fund that runs the most prestigious dating agency in the world, and incidentally employs famous scientists to do research.

afuzzyduck wrote:ITS MEANT TO BE FLUTTERSHY BUT I JUST SEE AAERIELE! CURSE YOU FORA!

EvanED
Posts: 4331
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI
Contact:

Re: Coding: Fleeting Thoughts

Postby EvanED » Mon Dec 17, 2012 4:08 pm UTC

Jplus wrote:Oh heavens. Windows is so ugly... :P

Oh, and POSIX has nothing like it of course. All it's functions are possible to use safely and are good examples of API design. :roll:

User avatar
Aaeriele
Posts: 2127
Joined: Tue Feb 23, 2010 3:30 am UTC
Location: San Francisco, CA

Re: Coding: Fleeting Thoughts

Postby Aaeriele » Mon Dec 17, 2012 4:21 pm UTC

Dropzone wrote:Things I have learned about RegQueryInfoKey today:
  • If the buffer that you provide for it to write the class name into (lpClass) has more than a certain amount of space available, the function will fail completely.
  • When that happens, the function returns an error code stating that the output buffer is too small.
  • When the output buffer actually is too small, it doesn't return the error code that the documentation says it does.
  • If you pass an output buffer of size 0, the function doesn't fail - it just silently pretends that the key doesn't have a class name.


Sounds like an integer overflow to me. >_>
Vaniver wrote:Harvard is a hedge fund that runs the most prestigious dating agency in the world, and incidentally employs famous scientists to do research.

afuzzyduck wrote:ITS MEANT TO BE FLUTTERSHY BUT I JUST SEE AAERIELE! CURSE YOU FORA!

User avatar
Dropzone
Posts: 405
Joined: Sun Dec 30, 2007 10:12 pm UTC
Location: North Lincs., UK

Re: Coding: Fleeting Thoughts

Postby Dropzone » Mon Dec 17, 2012 6:35 pm UTC

Yakk wrote:Sorry, is that an output buffer of size 0, or a nullptr to the output buffer size?

Often functions like that have a query-size interface where you ask it how much room is needed by passing in a null buffer, then calling it again with proper sized buffer.

Having tested it some more, it seems that its exact behaviour is: if lpcClass is non-NULL, and either lpClass is NULL or *lpcClass is 0, the function will set *lpcClass to 0 and return ERROR_SUCCESS. To make it set *lpcClass to the required buffer size and return ERROR_INSUFFICIENT_BUFFER, you have to allocate a one-character output buffer for lpClass to point to, and set *lpClass to 1.

Aaeriele wrote:Sounds like an integer overflow to me. >_>

I think you're right, actually. Here's the effect of passing various buffer sizes when querying a key with a 16-character class name:
  • 0: falsely succeeds (see above)
  • 1: fails
  • 15: fails
  • 16: succeeds
  • ...
  • 32767: succeeds
  • 32768: fails
  • ...
  • 65536 + 0: fails
  • 65536 + 1: fails
  • 65536 + 15: fails
  • 65536 + 16: succeeds
So it seems like they're casting the buffer size to a signed short at some point (WTF?!).

User avatar
Yakk
Poster with most posts but no title.
Posts: 11115
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting Thoughts

Postby Yakk » Mon Dec 17, 2012 7:03 pm UTC

Dropzone wrote:
Yakk wrote:Sorry, is that an output buffer of size 0, or a nullptr to the output buffer size?

Often functions like that have a query-size interface where you ask it how much room is needed by passing in a null buffer, then calling it again with proper sized buffer.

Having tested it some more, it seems that its exact behaviour is: if lpcClass is non-NULL, and either lpClass is NULL or *lpcClass is 0, the function will set *lpcClass to 0 and return ERROR_SUCCESS. To make it set *lpcClass to the required buffer size and return ERROR_INSUFFICIENT_BUFFER, you have to allocate a one-character output buffer for lpClass to point to, and set *lpClass to 1.

Naturally.

Code: Select all

bool bIsThereAValidOutputBuffer == lpcClass && *lpcClass && lpClass;
if (bThereIsAValidOutputBuffer) {
  short srcLength = ...;
  if (srcLength > short(*lpcClass)) {
    err = ERROR_INSUFFICIENT_BUFFER;
    goto cleanup;
  }
  ...
  lpClass[*lpcClass -1] = '\0\;
}

how else would you write this kind of thing?!

;)
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

EvanED
Posts: 4331
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI
Contact:

Re: Coding: Fleeting Thoughts

Postby EvanED » Wed Dec 19, 2012 8:39 pm UTC

Um. So I have a terrible question. I have the following function:

Code: Select all

template<typename Mapping>
typename Mapping::mapped_type const &
map_at(Mapping const & m, typename Mapping::key_type const & k)
{
    typename Mapping::const_iterator it = m.find(k);
    if (it == m.end()) {
        throw std::out_of_range("Key not present in map");
    }
    return it->second;
}

which I can use thusly:

Code: Select all

map<int, string> mymap;
mymap[0] = "zero";
map_at(mymap, 0); // => "zero"
map_at(mymap, 1); // => exception

but the problem is that due to this only-recently-fixed bug, I can't use it with Boost bimaps:

Code: Select all

bimap<int, string> mymap;
map_at(mymap.left, 0); // => error: boost::bimaps::views::map_view<...> has no member 'mapped_type'

because the designers inexplicably called it data_type instead of mapped_type. (key_type is present in both.)

Is there a way I can use SFINAE or enable_if or some other machinery to pick out the appropriate name? Complicating the fact is that I can't just produce two overloads, which would be easy enough, because mapped_type was recently added to Boost and so with that fix both presumably overloads would be enabled and the call would be ambiguous. So I either need to do it in a single function template definition (perhaps in concert with a traits class) or disable one of the overloads if both names are present.

(I'm not sure I'd go with such a solution considering that I bet the following would be simpler, but some of you might find it a fun challenge :-))

Code: Select all

        template<typename Mapping, typename Key, typename Value>
        Value const &
        map_at_impl(Mapping const & m, Key const & k)
        {
            typename Mapping::const_iterator it = m.find(k);
            if (it == m.end()) {
                throw std::out_of_range("Key not present in map");
            }
            return it->second;
        }
       

        /// Given a map 'm' and key 'k', return 'm[k]', except that it works
        /// when 'm' is const and it will throw an exception when 'k' is not
        /// present.
        template<typename Mapping>
        typename Mapping::mapped_type const &
        map_at(Mapping const & m, typename Mapping::key_type const & k)
        {
            return map_at_impl<Mapping,
                               typename Mapping::key_type,
                               typename Mapping::mapped_type>(m, k);
        }
           

        // This is because boost is dumb
        // (https://svn.boost.org/trac/boost/ticket/6031)
        template<typename Mapping>
        typename Mapping::data_type const &
        bimap_at(Mapping const & m, typename Mapping::key_type const & k)
        {
            return map_at_impl<Mapping,
                               typename Mapping::key_type,
                               typename Mapping::data_type>(m, k);
        }

:-)

User avatar
Yakk
Poster with most posts but no title.
Posts: 11115
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting Thoughts

Postby Yakk » Wed Dec 19, 2012 9:13 pm UTC

SFINAE on a "traits" class, like this:

Code: Select all

template<typename T, typename=void>
void map_target_type {};

template<typename T>
struct map_target_type< T, typename std::enable_if<sizeof(typename T::mapped_type) || true>::type > {
  typedef typename T::mapped_type type;
};

template<typename T>
struct map_target_type< T, typename std::enable_if< sizeof(typename T::data_type) || true >::type > {
  typedef typename T::data_type type;
};

template<typename Mapping>
typename map_target_type<Mapping>::type const &
map_at(Mapping const & m, typename Mapping::key_type const & k)
{
    typename Mapping::const_iterator it = m.find(k);
    if (it == m.end()) {
        throw std::out_of_range("Key not present in map");
    }
    return it->second;
}

should do it. (C++11 based, but slightly more convoluted stuff should work in C++03).

As a bonus, you could also specialize on value_type that is a pair, and presume it is a key/value pairing, and stuff the find algorithm into it as well.

Toss in careful use of std::begin and std::end style access, and templated find operation, and your map_at could work on vectors of sorted key/value pairs, or even on arrays of key/value pairs sorted by key.

A step more work would let it work transparently on sets (which are maps from a key to itself).
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
Yakk
Poster with most posts but no title.
Posts: 11115
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting Thoughts

Postby Yakk » Mon Dec 24, 2012 5:53 pm UTC

For your consideration:
http://ideone.com/QDuXKl
Spoiler:

Code: Select all

#include <type_traits>
 
template<typename... Types>
struct TypeList {};
 
template<typename T, typename List, typename=void>
struct IndexOf;
 
template<typename T, typename First, typename... Types>
struct IndexOf<T, TypeList<First, Types...>,
  typename std::enable_if<
    std::is_same< T, First >::value
  >::type
> {
  enum {value = 0};
};
 
template<typename T, typename First, typename... Types>
struct IndexOf<T, TypeList<First, Types...>,
  typename std::enable_if<
    !std::is_same< T, First >::value
  >::type
> {
  enum {value = 1+IndexOf<T, TypeList<Types...>>::value};
};
 
template<size_t n, typename List>
struct TypeAt;
 
template<size_t n, typename First, typename... Types>
struct TypeAt<n, TypeList<First, Types...>> {
    typedef typename TypeAt<n-1, TypeList<Types...>>::type type;
};
 
template<typename First, typename... Types>
struct TypeAt<0, TypeList<First, Types...>> {
    typedef First type;
};
 
template<typename Functor, typename List>
struct TypeDispatch {
    struct Helper {
        Helper( Functor const& f_ ):f(f_) {}
        Functor const& f;
        template<size_t n>
        void Call() const {
            typedef typename TypeAt<n, List>::type target_type;
            f.template Call<target_type>();
        }
    };
};
 
template<size_t max>
struct RuntimeSwitch {
    template<typename Functor>
    static bool Call( size_t n, Functor const& f ) {
        if (n == max) {
            f.template Call<max>();
            return true;
        } else {
            return RuntimeSwitch<max-1>::template Call( n, f );
        }
    }
};
 
template<>
struct RuntimeSwitch< size_t(-1) > {
    template<typename Functor>
    static bool Call( size_t n, Functor const& f ) {
        return false;
    }
};
 
template<typename List>
struct DynamicTypeDispatch;
 
template<typename... Types>
struct DynamicTypeDispatch<TypeList<Types...>> {
    template<typename Functor>
    static bool Call( size_t n, Functor const& f ) {
        typedef TypeDispatch<Functor, TypeList<Types...>> typeDispatch;
        typedef typename typeDispatch::Helper typeCaller;
        return RuntimeSwitch<sizeof...(Types)-1>::Call(n, typeCaller(f));
    }
};
 
#include <iostream>
#include <string>
struct Test {
    std::string s;
    Test( std::string s_ ):s(s_) {}
    template<typename T>
    void Call() const {
        std::cout << sizeof(T) << " == " << s.c_str() << " I hope\n";
    }
};
 
struct Test2Base {
    typedef TypeList<int, double, char> TestList;
    virtual void Dispatch( size_t n ) = 0;
    template<typename T>
    void Test(T const& unused) {
        Dispatch( IndexOf<T, TestList>::value );
    }
};
template<typename Child>
struct Test2CRTP: Test2Base {
    Child* self() { return static_cast<Child*>(this);}
    Child const* self() const { return static_cast<Child const*>(this); }
   
    template<typename T>
    void Call() const {
        self()->template TestImpl<T>();
    }
    virtual void Dispatch( size_t n ) {
        DynamicTypeDispatch<Test2Base::TestList>::Call( n, *this );
    }
};
struct Test2Impl: Test2CRTP<Test2Impl> {
  template<typename T>
  void TestImpl() const {
      std::cout << T(256.1) << "\n";
  }
};
int main()
{
    typedef TypeList<int, double> TestList;
    DynamicTypeDispatch<TestList>::Call( 0, Test("4") );
    DynamicTypeDispatch<TestList>::Call( 1, Test("8") );
   
    Test2Impl test2;
    test2.Test(int());
    test2.Test(char());
    test2.Test(double());
}

mwahahahahahahahaha.

So, this is a template pure virtual function trick. The set of types implemented is determined by a list of types, and the resulting glue is generated by template metaprogramming to move the template interface call through the virtual dispatcher back into template methods in the implementation class.

And the types are statically checked: if you call the interface with an unsupported type it will fail to compile. Add the type to the list and the implementation method is instantiated with that type as well.

This was in answer to the question 'why can we not have virtual template methods'.

It might be useful for double dispatch.
Last edited by Yakk on Sat Dec 29, 2012 1:32 pm UTC, edited 3 times in total.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
Aaeriele
Posts: 2127
Joined: Tue Feb 23, 2010 3:30 am UTC
Location: San Francisco, CA

Re: Coding: Fleeting Thoughts

Postby Aaeriele » Mon Dec 24, 2012 6:32 pm UTC

You all are terrible people.
Vaniver wrote:Harvard is a hedge fund that runs the most prestigious dating agency in the world, and incidentally employs famous scientists to do research.

afuzzyduck wrote:ITS MEANT TO BE FLUTTERSHY BUT I JUST SEE AAERIELE! CURSE YOU FORA!

User avatar
Jplus
Posts: 1721
Joined: Wed Apr 21, 2010 12:29 pm UTC
Location: Netherlands

Re: Coding: Fleeting Thoughts

Postby Jplus » Tue Dec 25, 2012 11:16 am UTC

That's a nice bit of black magic, Yakk. :P
"There are only two hard problems in computer science: cache coherence, naming things, and off-by-one errors." (Phil Karlton and Leon Bambrick)

coding and xkcd combined

(Julian/Julian's)

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Wed Dec 26, 2012 7:01 pm UTC

Java.

I have an interface

Code: Select all

interface FoobarIf<T> {}


And a few classes

Code: Select all

class Foobar0<T> implements FoobarIf<T> {}
class Foobar1<T> implements FoobarIf<T> {}

class Foobar2<T> implements FoobarIf<T> {
 Class<? extends FoobarIf<T>> getFoobarInstanceClass() {
    return Foobar1<T>.class; // <--- How can I make this work ?!
  }
}


I can't get it to work.

"new Foobar1<T>();" works. Why not "Foobar1<T>.class"?!

--edit--

Oh. You can apparently cast from Foobar1.class to Class<? extends FoobarIf<T>>. Sometimes I forget how stupid generics are, and mistakenly expect them to behave like a type system.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
Jplus
Posts: 1721
Joined: Wed Apr 21, 2010 12:29 pm UTC
Location: Netherlands

Re: Coding: Fleeting Thoughts

Postby Jplus » Wed Dec 26, 2012 9:37 pm UTC

Is that the crazy thing they call type erasure?
"There are only two hard problems in computer science: cache coherence, naming things, and off-by-one errors." (Phil Karlton and Leon Bambrick)

coding and xkcd combined

(Julian/Julian's)

User avatar
headprogrammingczar
Posts: 3072
Joined: Mon Oct 22, 2007 5:28 pm UTC
Location: Beaming you up

Re: Coding: Fleeting Thoughts

Postby headprogrammingczar » Thu Dec 27, 2012 12:58 am UTC

Yes. Specifically, it's the interaction between "types vanish at runtime" and "you can write code that requires type info at runtime".
<quintopia> You're not crazy. you're the goddamn headprogrammingspock!
<Weeks> You're the goddamn headprogrammingspock!
<Cheese> I love you

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Thu Dec 27, 2012 3:54 pm UTC

Java generics make me mad. It's a damn half measure. It's like they started out blindly trying to add C++ style templates to java, figured out 7 months into the project "Oh, how the heck do we deal with template instantiation?", were faced with the choices of either making a drastic change to the language, or scrapping the project all together; and pussied out and invented type erasure, which butchers the language feature to the point where it's barely useful anymore.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
Link
Posts: 1399
Joined: Sat Mar 07, 2009 11:33 am UTC
Location: ᘝᓄᘈᖉᐣ
Contact:

Re: Coding: Fleeting Thoughts

Postby Link » Mon Dec 31, 2012 9:43 am UTC

C++/templates question. Suppose I have the following:

Code: Select all

#include <boost/array.hpp>

// Linear Algebra vector in R^N
template<std::size_t N> class LAVector
{
    public:
        LAVector<N> (const boost::array<double, N> &values);
};


Is there some way to create a constructor where, instead of using a boost::array<double, N>, I simply accept exactly N double parameters, so that I can write LAVector<2> (1.0, 0.0), LAVector<3> (0.0, 1.0, 0.0), etcetera, instead of LAVector<2> (((boost::array<double, 2>) {{1.0, 0.0}})) and LAVector<3> (((boost::array<double, 3>) {{0.0, 1.0, 0.0}}))? The latter is ugly and causes GCC to complain if -pedantic is used. The proper solution would be using per-item initialisation of the boost array, but that's even more verbose.

(This stuff is exactly why I prefer C to C++, but templates are useful for what I want to do.)

User avatar
gordo
Posts: 44
Joined: Wed Oct 10, 2012 2:17 pm UTC

Re: Coding: Fleeting Thoughts

Postby gordo » Mon Dec 31, 2012 12:45 pm UTC

Link wrote:C++/templates question. Suppose I have the following:

Code: Select all

#include <boost/array.hpp>

// Linear Algebra vector in R^N
template<std::size_t N> class LAVector
{
    public:
        LAVector<N> (const boost::array<double, N> &values);
};


Is there some way to create a constructor where, instead of using a boost::array<double, N>, I simply accept exactly N double parameters, so that I can write LAVector<2> (1.0, 0.0), LAVector<3> (0.0, 1.0, 0.0), etcetera, instead of LAVector<2> (((boost::array<double, 2>) {{1.0, 0.0}})) and LAVector<3> (((boost::array<double, 3>) {{0.0, 1.0, 0.0}}))? The latter is ugly and causes GCC to complain if -pedantic is used. The proper solution would be using per-item initialisation of the boost array, but that's even more verbose.

(This stuff is exactly why I prefer C to C++, but templates are useful for what I want to do.)


I think you can use the ellipsis and va_* macros. Not very pretty either, but it does what you want.

User avatar
Yakk
Poster with most posts but no title.
Posts: 11115
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting Thoughts

Postby Yakk » Mon Dec 31, 2012 3:15 pm UTC

Link wrote:C++/templates question. Suppose I have the following:
Spoiler:

Code: Select all

#include <boost/array.hpp>

// Linear Algebra vector in R^N
template<std::size_t N> class LAVector
{
    public:
        LAVector<N> (const boost::array<double, N> &values);
};

Is there some way to create a constructor where, instead of using a boost::array<double, N>, I simply accept exactly N double parameters, so that I can write LAVector<2> (1.0, 0.0), LAVector<3> (0.0, 1.0, 0.0), etcetera

Yes! I am going to assume C++11 support is reasonable in your compiler, because otherwise this sucks to write. The fact you are using boost for arrays makes me think you may be doomed.

Code: Select all

    #include <type_traits>
    #include <array>

    template<typename... Types>
    struct type_sequence {};
   
    template<typename sequence, typename=void>
    struct is_all_doubles_helper;
   
    // First element decays to double, is all doubles iff rest of sequence is all doubles:
    template<typename First, typename... Types>
    struct is_all_doubles_helper<
      type_sequence< First, Types... >,
      typename std::enable_if<std::is_same<typename std::decay<First>::type, double>::value>::type
    >: is_all_doubles_helper< type_sequence<Types...> >
    {};

    // First element doesn't decay to double, not a sequence of all doubles:
    template<typename First, typename... Types>
    struct is_all_doubles_helper<
      type_sequence< First, Types... >,
      typename std::enable_if<!std::is_same<typename std::decay<First>::type, double>::value>::type
    >: std::false_type
    {};

    // empty sequence is all doubles:
    template<>
    struct is_all_doubles_helper<
      type_sequence<>,
      void
    >: std::true_type
    {};

    template<typename... Types>
    struct is_all_doubles:is_all_doubles_helper<type_sequence<Types...>> {};

    template<std::size_t N> class LAVector {
    // helper methods to initialize the data:
        template<std::size_t starting_at>
        void Init() {}
        template<std::size_t starting_at, typename First, typename... Types>
        void Init(First first, Types... args) {
          (*this)[starting_at] = first;
          Init<starting_at+1>( args... );
        }
        std::array<double, N> data;
      public:
        double& operator[]( std::size_t index ) { return data[index]; }
        LAVector(const std::array<double, N> &values):data(values) {}

        // Is valid IFF the types are all doubles, and there are exactly N of them:     
        template<typename... Types, typename=typename std::enable_if<is_all_doubles<Types...>::value && (sizeof...(Types)==N)>::type>
        LAVector(Types... args) {
          Init<0>( args... );
        };
    };
       
    int main() {
      LAVector<2> test(2.0, 3.14);
      LAVector<1> test2(2.0);
      LAVector<3> test3(1.0, 2.0, 3.0);
      LAVector<1> test4(1.0, 2.0); // fails to compile
      LAVector<1> test5(2); // fails to compile
      LAVector<1> test6(2.f); // fails to compile
    };

is_all_doubles can be relaxed, because what you really care about is "can all be implicitly converted to doubles"... probably.

If you drop the is_all_doubles from the enable_if, a problem occurs in that the "eat exactly N" template constructor eats anything with exactly N elements, which can block other constructors from being picked when you want them to. Relaxing is_all_doubles to being "is_all_things_that_can_be_implicitly_converted_to_double" is possible.

It is a bit trickier however.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
Link
Posts: 1399
Joined: Sat Mar 07, 2009 11:33 am UTC
Location: ᘝᓄᘈᖉᐣ
Contact:

Re: Coding: Fleeting Thoughts

Postby Link » Mon Dec 31, 2012 4:44 pm UTC

I could possibly go full C++11 (which is something I'm definitely considering, because I'm also running into some things for which constexpr would be very nice), but I'd prefer to keep things compatible with slightly older compilers. The fact that it's that much trouble even in C++11 means I'll just mark this "not worth it" -- though it's good to know that it's not entirely impossible!

gordo: the problem with the cstdarg macros is that they're extremely lax in what they allow. I want to have as much compile-time checking as possible, which is why I want the enhanced array types in the first place.

User avatar
Yakk
Poster with most posts but no title.
Posts: 11115
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting Thoughts

Postby Yakk » Mon Dec 31, 2012 6:39 pm UTC

There is initializer lists, but I do not know them well.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
Yakk
Poster with most posts but no title.
Posts: 11115
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting Thoughts

Postby Yakk » Mon Dec 31, 2012 7:28 pm UTC

So did some research.

An initializer list ctor makes coming from double easy, but you do not get to limit the count at compile time.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
Aaeriele
Posts: 2127
Joined: Tue Feb 23, 2010 3:30 am UTC
Location: San Francisco, CA

Re: Coding: Fleeting Thoughts

Postby Aaeriele » Tue Jan 01, 2013 1:44 am UTC

Link wrote:I could possibly go full C++1


Never go full C++.
Vaniver wrote:Harvard is a hedge fund that runs the most prestigious dating agency in the world, and incidentally employs famous scientists to do research.

afuzzyduck wrote:ITS MEANT TO BE FLUTTERSHY BUT I JUST SEE AAERIELE! CURSE YOU FORA!

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Tue Jan 01, 2013 3:47 am UTC

Is there a reason why there's always functions in production code that are like 1023 lines long? Screen upon screen upon screen of code.

When I write code, most of my functions tend to be around 10-20 lines long. I virtually never produce functions longer than a screen, before I break out helper functions that reduce the length of the function.

Is this a strange thing to do?
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

Rysto
Posts: 1460
Joined: Wed Mar 21, 2007 4:07 am UTC

Re: Coding: Fleeting Thoughts

Postby Rysto » Tue Jan 01, 2013 4:20 am UTC

I've heard that kind of thing referred to as a "software combover". No one sets out to write a monstrous function, but over time the code acquires fixes and little features here and there without a lot of thought to how it should fit into the design. Given enough time you can be left with awful code.

I find that this is especially a problem in proprietary code. The open source world is largely free of business concerns and pressing deadlines. A well-run project will reject bad code. In my work I find that there is a constant focus on hitting the current quarter which can lead to all kinds of unacceptable code going in. And the problem just compounds itself over time.

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Tue Jan 01, 2013 4:42 am UTC

In most cases I see, it isn't even like the code is hard to refactor. Chopping them into 2-3 functions of large, but acceptably sized would oftentimes take about a minute. Add 5 minutes for running the unit tests, and another minute for source control.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
Xeio
Friends, Faidites, Countrymen
Posts: 5101
Joined: Wed Jul 25, 2007 11:12 am UTC
Location: C:\Users\Xeio\
Contact:

Re: Coding: Fleeting Thoughts

Postby Xeio » Tue Jan 01, 2013 7:46 am UTC

You, sir, name? wrote:When I write code, most of my functions tend to be around 10-20 lines long. I virtually never produce functions longer than a screen, before I break out helper functions that reduce the length of the function.

Is this a strange thing to do?
I semi-regularly write longer functions than that, but it varies depending on what I'm working on. I usually don't split a function just to keep it to a certain size. My primary goal in splitting functions is to reduce duplicated code.

There probably is a point at which I might try to split a function if I can due to length, but it would be beyond a page of code for me to do that.

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Tue Jan 01, 2013 7:56 am UTC

A more practical benefit of short functions than readability is that it makes much it easier to poke and prod with unit tests.

Maybe it's a function of how you design your code? I rely almost exclusively on bottom-up design, to the point where I typically have most of the helper functions before I write the function that uses them.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
phlip
Restorer of Worlds
Posts: 7569
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: Coding: Fleeting Thoughts

Postby phlip » Tue Jan 01, 2013 1:38 pm UTC

Wow. I'm impressed with how thoroughly broken this code is.

Another forum I frequent currently has their page completely broken (for me) by a misbehaving ad script. It's still usable if you have adblock, but if you're without then you're boned. I poked around in it, but it's full of exciting things like:

Code: Select all

document.write('<SCR'+'IPT type="text/javascript">');
document.write('document.write(\'<scr\'+\'ipt type="text/javascript" src="http://ad.360yield.com/adj?p=17195&w=160&h=600&tz=\'+(new Date().getTimezoneOffset())+\'&click3rd="><\/scr\'+\'ipt>\');');
document.write('</SCR'+'IPT>');
document.write('');
document.write('');
that make me close the tab automatically by reflex, to avoid additional brain damage.

However, I did eventually find a script that said, in part:

Code: Select all

[snip some JS code]
document.writeln("[snip some HTML] <script type=\"text\/javascript\"> [snip some JS code] [snip some random XML]");

Notably: the document.write call writes a <script> tag but no </script> tag. As a result, everything below this on the page (including stuff that's supposed to be part of the page proper, not just ad-related stuff) is parsed as being part of a massive script element, and the resulting page appears completely blank below the ad.

And I'm left thinking just: "Why?". Aimed at both whoever wrote this script, and whoever decided that the document.write should work in this way (or, more accurately, whoever decided that it should exist at all).

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
Link
Posts: 1399
Joined: Sat Mar 07, 2009 11:33 am UTC
Location: ᘝᓄᘈᖉᐣ
Contact:

Re: Coding: Fleeting Thoughts

Postby Link » Tue Jan 01, 2013 6:16 pm UTC

Aaeriele wrote:
Link wrote:I could possibly go full C++1


Never go full C++.

Normally, I'd agree, but... it's too late! Augh!

I'm slightly ashamed to admit that I'm now emerging GCC 4.7.2 because I want alias templates. I have a template<std::size_t S> function that returns a std::array< std::array<int, S>, e3(S)-1> object, where e3 is a constexpr function that calculates 3x; keeping that as-is is just evil, and using a macro (my current solution) is quite ugly. This is rapidly devolving into a Lovecraftian horror, but doing it in C would be even worse. Gaaah!

User avatar
Yakk
Poster with most posts but no title.
Posts: 11115
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting Thoughts

Postby Yakk » Tue Jan 01, 2013 7:43 pm UTC

C++11: answers to questions you didn't even know you wanted to ask.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
Dopefish
Posts: 855
Joined: Sun Sep 20, 2009 5:46 am UTC
Location: The Well of Wishes

Re: Coding: Fleeting Thoughts

Postby Dopefish » Tue Jan 01, 2013 10:48 pm UTC

Is C++11 a seperate thing from C++ in the same way C++ is seperate from C, or is it just the 'new version' of C++?

Also, is C++11 read as "C plus plus one one" or "C plus plus eleven"?

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Tue Jan 01, 2013 11:22 pm UTC

C++11 is the latest version of C++ (previous versions being C++03 and C++98). Still C++.

phlip wrote:Wow. I'm impressed with how thoroughly broken this code is.

Spoiler:
Another forum I frequent currently has their page completely broken (for me) by a misbehaving ad script. It's still usable if you have adblock, but if you're without then you're boned. I poked around in it, but it's full of exciting things like:

Code: Select all

document.write('<SCR'+'IPT type="text/javascript">');
document.write('document.write(\'<scr\'+\'ipt type="text/javascript" src="http://ad.360yield.com/adj?p=17195&w=160&h=600&tz=\'+(new Date().getTimezoneOffset())+\'&click3rd="><\/scr\'+\'ipt>\');');
document.write('</SCR'+'IPT>');
document.write('');
document.write('');
that make me close the tab automatically by reflex, to avoid additional brain damage.

However, I did eventually find a script that said, in part:

Code: Select all

[snip some JS code]
document.writeln("[snip some HTML] <script type=\"text\/javascript\"> [snip some JS code] [snip some random XML]");

Notably: the document.write call writes a <script> tag but no </script> tag. As a result, everything below this on the page (including stuff that's supposed to be part of the page proper, not just ad-related stuff) is parsed as being part of a massive script element, and the resulting page appears completely blank below the ad.

And I'm left thinking just: "Why?". Aimed at both whoever wrote this script, and whoever decided that the document.write should work in this way (or, more accurately, whoever decided that it should exist at all).


I'm surprised browsers still support document.write(). Javascript can access the DOM, and if you feel an irresistible need to insert raw HTML into an element, there is innerHTML. document.write() is just wrong, to a degree unparalleled by most JS features except perhaps eval()
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
Yakk
Poster with most posts but no title.
Posts: 11115
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting Thoughts

Postby Yakk » Wed Jan 02, 2013 12:33 am UTC

Dopefish wrote:Also, is C++11 read as "C plus plus one one" or "C plus plus eleven"?
It is pronounced "Cee plus plus oh ex".
You, sir, name? wrote:C++11 is the latest version of C++ (previous versions being C++03 and C++98). Still C++.
However, most compilers do not currently have full support for C++11 features as yet. Most have partial support. So being leery about recommending C++11 solutions at this point is reasonable, and noting when you use the features in sample code is important so as not to confuse the copy/paster.

So relying on C++11 features means that not all compilers will be able to compile your code. Fortunately, in almost every case the failure will be a failure to compile, not unexpected or undefined behavior.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

EvanED
Posts: 4331
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI
Contact:

Re: Coding: Fleeting Thoughts

Postby EvanED » Wed Jan 02, 2013 12:49 am UTC

Yakk wrote:So relying on C++11 features means that not all compilers will be able to compile your code. Fortunately, in almost every case the failure will be a failure to compile, not unexpected or undefined behavior.

Or you could spend an hour trying to debug your use of <regex> only to discover some dick decided to distribute this with GCC. :roll:

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Wed Jan 02, 2013 12:49 am UTC

Yakk wrote:
Dopefish wrote:Also, is C++11 read as "C plus plus one one" or "C plus plus eleven"?
It is pronounced "Cee plus plus oh ex".
You, sir, name? wrote:C++11 is the latest version of C++ (previous versions being C++03 and C++98). Still C++.
However, most compilers do not currently have full support for C++11 features as yet. Most have partial support. So being leery about recommending C++11 solutions at this point is reasonable, and noting when you use the features in sample code is important so as not to confuse the copy/paster.

So relying on C++11 features means that not all compilers will be able to compile your code. Fortunately, in almost every case the failure will be a failure to compile, not unexpected or undefined behavior.


If the project finish-date is sufficiently far down the line, I don't really see a problem. C++11 support will be there in a couple of years.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
Yakk
Poster with most posts but no title.
Posts: 11115
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting Thoughts

Postby Yakk » Wed Jan 02, 2013 3:02 am UTC

EvanED wrote:
Yakk wrote:So relying on C++11 features means that not all compilers will be able to compile your code. Fortunately, in almost every case the failure will be a failure to compile, not unexpected or undefined behavior.

Or you could spend an hour trying to debug your use of <regex> only to discover some dick decided to distribute this with GCC. :roll:

Code: Select all

 * @todo Implement this function.

Fuck.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
Xanthir
My HERO!!!
Posts: 5400
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Wed Jan 02, 2013 5:11 am UTC

You, sir, name? wrote:I'm surprised browsers still support document.write(). Javascript can access the DOM, and if you feel an irresistible need to insert raw HTML into an element, there is innerHTML. document.write() is just wrong, to a degree unparalleled by most JS features except perhaps eval()

Believe me, if it was possible to drop it, we would have done so with extreme prejudice. It's one of the worst features in the platform, infecting so much of the internal algorithms with unnecessary and stupid complexity.

I still think we should carrot-and-stick our way into an actual "version" of DOM, maybe something like what strict mode is for JS itself, and turn off document.write in the new version.
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Wed Jan 02, 2013 5:33 am UTC

Add a speed-up loop in "classic" javascript. Remove it in strict.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Thu Jan 03, 2013 12:11 pm UTC

Oh my god.

https://github.com/munificent/vigil

A programming language that's Lawful Good.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
Xenomortis
Not actually a special flower.
Posts: 1446
Joined: Thu Oct 11, 2012 8:47 am UTC

Re: Coding: Fleeting Thoughts

Postby Xenomortis » Thu Jan 03, 2013 4:53 pm UTC

I think you have a very loose definition of "Good".
Image

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Thu Jan 03, 2013 5:11 pm UTC

As I read it, I was imagining it being designed by a paladin of Torm.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 10 guests