Q:

When one user function is altered, other user function doesn't return correct data

I have two user functions, one calling the other.
First of them is defined as
CREATE FUNCTION [dbo].[fnTest] (
@a INT
, @b INT
)
RETURNS @data TABLE (
    A varchar(20),
    B varchar(20),
    C varchar(20)
    )
AS BEGIN
        INSERT INTO @data
        SELECT 'A' A, 'B' B, 'C' C
   RETURN
END

and the other is a plain select from the first one:
CREATE FUNCTION [dbo].[fnTest2] (
    @a INT
    , @b INT
    , @c VARCHAR(20)
    ) RETURNS TABLE
    AS
    RETURN SELECT * FROM dbo.fnTest(@a, @b) WHERE C = @c

When I ALTER the first function, adding a new column to the result (e.g. D), the second function is still unaltered and returns only the original columns (i.e. it completely ignores column D) until it is ALTERed as well.
I am pretty much clear on how to fix this (either specifying all the columns in Test2 or recreating Test2 by ALTER command), but the question I have is - why do I need to do that? Is there some setting that will rebuild this automatically?
For the record, the ALTER query I used is:
ALTER FUNCTION [dbo].[fnTest] (
    @a INT
    , @b INT
    )
RETURNS @data TABLE (
    A varchar(20),
    B varchar(20),
    C varchar(20),
    D varchar(20)
    )
AS BEGIN
        INSERT INTO @data
        SELECT 'A' A, 'B' B, 'C' C, 'D' D
    RETURN
END

A:

You can refresh metadata using sp_refreshsqlmodule:

Updates the metadata for the specified non-schema-bound stored
  procedure, user-defined function, view, DML trigger, database-level
  DDL trigger, or server-level DDL trigger in the current database.
  Persistent metadata for these objects, such as data types of
  parameters, can become outdated because of changes to their underlying
  objects.

CREATE FUNCTION [dbo].[fnTest] (
@a INT
, @b INT
)
RETURNS @data TABLE (
    A varchar(20),
    B varchar(20),
    C varchar(20)
    )
AS BEGIN
        INSERT INTO @data
        SELECT 'A' A, 'B' B, 'C' C
   RETURN
END;
GO

CREATE FUNCTION [dbo].[fnTest2] (
    @a INT
    , @b INT
    , @c VARCHAR(20)
    ) RETURNS TABLE
    AS
    RETURN SELECT * FROM dbo.fnTest(@a, @b) WHERE C = @c
    GO

    ALTER FUNCTION [dbo].[fnTest] (
    @a INT
    , @b INT
    )
RETURNS @data TABLE (
    A varchar(20),
    B varchar(20),
    C varchar(20),
    D varchar(20)
    )
AS BEGIN
        INSERT INTO @data
        SELECT 'A' A, 'B' B, 'C' C, 'D' D
    RETURN
END
GO

EXEC sys.sp_refreshsqlmodule 'dbo.fnTest2';

SqlFiddleDemo
Or you can ue WITH SCHEMABINDING:

If a user-defined function is not created with the SCHEMABINDING
  clause, changes that are made to underlying objects can affect the
  definition of the function and produce unexpected results when it is
  invoked. We recommend that you implement one of the following methods
  to ensure that the function does not become outdated because of
  changes to its underlying objects:
1) Specify the WITH SCHEMABINDING clause when you are creating the function. This ensures that the objects referenced in the function
  definition cannot be modified unless the function is also modified.
2) Execute the sp_refreshsqlmodule stored procedure after modifying any object that is specified in the definition of the function.

Keep in mind that SELECT * is not allowed when SCHEMABINDING is used.

