Set default values if no arg given
diff --git a/bool.go b/bool.go
index ead8dba..04c9b5a 100644
--- a/bool.go
+++ b/bool.go
@@ -50,31 +50,31 @@
 // BoolVar defines a bool flag with specified name, default value, and usage string.
 // The argument p points to a bool variable in which to store the value of the flag.
 func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {
-	f.VarP(newBoolValue(value, p), name, "", usage)
+	f.BoolVarP(p, name, "", value, usage)
 }
 
 // Like BoolVar, but accepts a shorthand letter that can be used after a single dash.
 func (f *FlagSet) BoolVarP(p *bool, name, shorthand string, value bool, usage string) {
-	f.VarP(newBoolValue(value, p), name, shorthand, usage)
+	flag := f.VarPF(newBoolValue(value, p), name, shorthand, usage)
+	flag.NoOptDefVal = "true"
 }
 
 // BoolVar defines a bool flag with specified name, default value, and usage string.
 // The argument p points to a bool variable in which to store the value of the flag.
 func BoolVar(p *bool, name string, value bool, usage string) {
-	CommandLine.VarP(newBoolValue(value, p), name, "", usage)
+	BoolVarP(p, name, "", value, usage)
 }
 
 // Like BoolVar, but accepts a shorthand letter that can be used after a single dash.
 func BoolVarP(p *bool, name, shorthand string, value bool, usage string) {
-	CommandLine.VarP(newBoolValue(value, p), name, shorthand, usage)
+	flag := CommandLine.VarPF(newBoolValue(value, p), name, shorthand, usage)
+	flag.NoOptDefVal = "true"
 }
 
 // Bool defines a bool flag with specified name, default value, and usage string.
 // The return value is the address of a bool variable that stores the value of the flag.
 func (f *FlagSet) Bool(name string, value bool, usage string) *bool {
-	p := new(bool)
-	f.BoolVarP(p, name, "", value, usage)
-	return p
+	return f.BoolP(name, "", value, usage)
 }
 
 // Like Bool, but accepts a shorthand letter that can be used after a single dash.
@@ -87,10 +87,11 @@
 // Bool defines a bool flag with specified name, default value, and usage string.
 // The return value is the address of a bool variable that stores the value of the flag.
 func Bool(name string, value bool, usage string) *bool {
-	return CommandLine.BoolP(name, "", value, usage)
+	return BoolP(name, "", value, usage)
 }
 
 // Like Bool, but accepts a shorthand letter that can be used after a single dash.
 func BoolP(name, shorthand string, value bool, usage string) *bool {
-	return CommandLine.BoolP(name, shorthand, value, usage)
+	b := CommandLine.BoolP(name, shorthand, value, usage)
+	return b
 }
diff --git a/bool_test.go b/bool_test.go
index a2e1c5d..febf667 100644
--- a/bool_test.go
+++ b/bool_test.go
@@ -59,7 +59,8 @@
 func setUpFlagSet(tristate *triStateValue) *FlagSet {
 	f := NewFlagSet("test", ContinueOnError)
 	*tristate = triStateFalse
-	f.VarP(tristate, "tristate", "t", "tristate value (true, maybe or false)")
+	flag := f.VarPF(tristate, "tristate", "t", "tristate value (true, maybe or false)")
+	flag.NoOptDefVal = "true"
 	return f
 }
 
@@ -162,3 +163,18 @@
 		t.Fatal("expected an error but did not get any, tristate has value", tristate)
 	}
 }
+
+func TestBoolP(t *testing.T) {
+	b := BoolP("bool", "b", false, "bool value in CommandLine")
+	c := BoolP("c", "c", false, "other bool value")
+	args := []string{"--bool"}
+	if err := CommandLine.Parse(args); err != nil {
+		t.Error("expected no error, got ", err)
+	}
+	if *b != true {
+		t.Errorf("expected b=true got b=%s", b)
+	}
+	if *c != false {
+		t.Errorf("expect c=false got c=%s", c)
+	}
+}
diff --git a/flag.go b/flag.go
index 20cdeb1..55c381c 100644
--- a/flag.go
+++ b/flag.go
@@ -152,6 +152,7 @@
 	Value       Value               // value as set
 	DefValue    string              // default value (as text); for usage message
 	Changed     bool                // If the user set the value (or if left to default)
+	NoOptDefVal string              //default value (as text); if the flag is on the command line without any options
 	Deprecated  string              // If this flag is deprecated, this string is the new or now thing to use
 	Annotations map[string][]string // used by cobra.Command  bash autocomple code
 }
@@ -341,16 +342,25 @@
 		if len(flag.Deprecated) > 0 {
 			return
 		}
-		format := "--%s=%s: %s\n"
-		if _, ok := flag.Value.(*stringValue); ok {
-			// put quotes on the value
-			format = "--%s=%q: %s\n"
-		}
+		format := ""
+		// ex: w/ option string argument '-%s, --%s[=%q]: %s\n'
 		if len(flag.Shorthand) > 0 {
-			format = "  -%s, " + format
+			format = "  -%s, --%s"
 		} else {
-			format = "   %s   " + format
+			format = "   %s   --%s"
 		}
+		if len(flag.NoOptDefVal) > 0 {
+			format = format + "["
+		}
+		if _, ok := flag.Value.(*stringValue); ok {
+			format = format + "=%q"
+		} else {
+			format = format + "=%s"
+		}
+		if len(flag.NoOptDefVal) > 0 {
+			format = format + "]"
+		}
+		format = format + ": %s\n"
 		fmt.Fprintf(f.out(), format, flag.Shorthand, flag.Name, flag.DefValue, flag.Usage)
 	})
 }
@@ -443,8 +453,8 @@
 	f.VarP(value, name, "", usage)
 }
 
-// Like Var, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
+// Like VarP, but returns the flag created
+func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *Flag {
 	// Remember the default value as a string; it won't change.
 	flag := &Flag{
 		Name:      name,
@@ -454,6 +464,12 @@
 		DefValue:  value.String(),
 	}
 	f.AddFlag(flag)
+	return flag
+}
+
+// Like Var, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
+	_ = f.VarPF(value, name, shorthand, usage)
 }
 
 func (f *FlagSet) AddFlag(flag *Flag) {
@@ -566,11 +582,11 @@
 	if len(split) == 2 {
 		// '--flag=arg'
 		value = split[1]
-	} else if bv, ok := flag.Value.(boolFlag); ok && bv.IsBoolFlag() {
-		// '--flag' (where flag is a bool)
-		value = "true"
+	} else if len(flag.NoOptDefVal) > 0 {
+		// '--flag' (arg was optional)
+		value = flag.NoOptDefVal
 	} else {
-		// '--flag' (where flag was not a bool)
+		// '--flag' (arg was required)
 		err = f.failf("flag needs an argument: %s", s)
 		return
 	}
@@ -598,8 +614,8 @@
 	if len(shorthands) > 2 && shorthands[1] == '=' {
 		value = shorthands[2:]
 		outShorts = ""
-	} else if bv, ok := flag.Value.(boolFlag); ok && bv.IsBoolFlag() {
-		value = "true"
+	} else if len(flag.NoOptDefVal) > 0 {
+		value = flag.NoOptDefVal
 	} else if len(shorthands) > 1 {
 		value = shorthands[1:]
 		outShorts = ""
diff --git a/flag_test.go b/flag_test.go
index 9fbb785..67a6a27 100644
--- a/flag_test.go
+++ b/flag_test.go
@@ -27,6 +27,7 @@
 	test_string                  = String("test_string", "0", "string value")
 	test_float64                 = Float64("test_float64", 0, "float64 value")
 	test_duration                = Duration("test_duration", 0, "time.Duration value")
+	test_optional_int            = Int("test_optional_int", 0, "optional int value")
 	normalizeFlagNameInvocations = 0
 )
 
@@ -58,7 +59,7 @@
 		}
 	}
 	VisitAll(visitor)
-	if len(m) != 8 {
+	if len(m) != 9 {
 		t.Error("VisitAll misses some flags")
 		for k, v := range m {
 			t.Log(k, *v)
@@ -81,9 +82,10 @@
 	Set("test_string", "1")
 	Set("test_float64", "1")
 	Set("test_duration", "1s")
+	Set("test_optional_int", "1")
 	desired = "1"
 	Visit(visitor)
-	if len(m) != 8 {
+	if len(m) != 9 {
 		t.Error("Visit fails after set")
 		for k, v := range m {
 			t.Log(k, *v)
@@ -161,6 +163,10 @@
 	ipFlag := f.IP("ip", net.ParseIP("127.0.0.1"), "ip value")
 	maskFlag := f.IPMask("mask", ParseIPv4Mask("0.0.0.0"), "mask value")
 	durationFlag := f.Duration("duration", 5*time.Second, "time.Duration value")
+	optionalIntNoValueFlag := f.Int("optional-int-no-value", 0, "int value")
+	f.Lookup("optional-int-no-value").NoOptDefVal = "9"
+	optionalIntWithValueFlag := f.Int("optional-int-with-value", 0, "int value")
+	f.Lookup("optional-int-no-value").NoOptDefVal = "9"
 	extra := "one-extra-argument"
 	args := []string{
 		"--bool",
@@ -181,6 +187,8 @@
 		"--ip=10.11.12.13",
 		"--mask=255.255.255.0",
 		"--duration=2m",
+		"--optional-int-no-value",
+		"--optional-int-with-value=42",
 		extra,
 	}
 	if err := f.Parse(args); err != nil {
@@ -294,6 +302,12 @@
 	if _, err := f.GetInt("duration"); err == nil {
 		t.Error("GetInt parsed a time.Duration?!?!")
 	}
+	if *optionalIntNoValueFlag != 9 {
+		t.Error("optional int flag should be the default value, is ", *optionalIntNoValueFlag)
+	}
+	if *optionalIntWithValueFlag != 42 {
+		t.Error("optional int flag should be 42, is ", *optionalIntWithValueFlag)
+	}
 	if len(f.Args()) != 1 {
 		t.Error("expected one argument, got", len(f.Args()))
 	} else if f.Args()[0] != extra {