When reading the doc of Solidity.I found out that the following is hard to understand or maybe I misunderstood something, any help is much appreciated.The document says:

The following example shows how to use memory types and internal functions in libraries in order to implement custom types without the overhead of external function calls:

pragma solidity ^0.4.0;

library BigInt {
    struct bigint {
        uint[] limbs;
    }

    function fromUint(uint x) internal returns (bigint r) {
        r.limbs = new uint[](1);
        r.limbs[0] = x;
    }

    function add(bigint _a, bigint _b) internal returns (bigint r) {
        r.limbs = new uint[](max(_a.limbs.length, _b.limbs.length));
        uint carry = 0;
        for (uint i = 0; i < r.limbs.length; ++i) {
            uint a = limb(_a, i);
            uint b = limb(_b, i);
            r.limbs[i] = a + b + carry;
            if (a + b < a || (a + b == uint(-1) && carry > 0))
                carry = 1;
            else
                carry = 0;
        }
        if (carry > 0) {
            // too bad, we have to add a limb
            uint[] memory newLimbs = new uint[](r.limbs.length + 1);
            for (i = 0; i < r.limbs.length; ++i)
                newLimbs[i] = r.limbs[i];
            newLimbs[i] = carry;
            r.limbs = newLimbs;
        }
    }

    function limb(bigint _a, uint _limb) internal returns (uint) {
        return _limb < _a.limbs.length ? _a.limbs[_limb] : 0;
    }

    function max(uint a, uint b) private returns (uint) {
        return a > b ? a : b;
    }
}


contract C {
    using BigInt for BigInt.bigint;

    function f() {
        var x = BigInt.fromUint(7);
        var y = BigInt.fromUint(uint(-1));
        var z = x.add(y);
    }
}

My Question is that, is using A for B a good practice ? for here it says when using this ,there is no overhead of external function call.But in the document it also says:

The calls to Set.contains, Set.insert and Set.remove are all compiled as calls (DELEGATECALL) to an external contract/library.

but code comment in the document also says both ways are just identical:

// Here, all variables of type Set.Data have
// corresponding member functions.
// The following function call is **identical** to
// Set.insert(knownValues, value)
require(knownValues.insert(value));

The way the function calls on a library are compiled is determined by the visibility modifier. There are two ways:
If you use public functions you will have the external overhead as the library will need to be deployed separately. In that case your contract's bytecode must be linked to the library once it is deployed.

If you use internal functions, those will be compiled into the bytecode of the contract which uses the library. It behaves similar to inherited functions. That way your contracts bytecode will get bigger.
So which visibility to use depends on your use case.

To answer your question: the use of the using for directive is just a matter of your design and does not affect the way the contract or library is compiled.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.